tags:

views:

306

answers:

1

I'm trying to write a regular expression replace expression that will replace a fully-qualified generic type name with its C# equivalent. For example, the following text:

System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[MyNamespace.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

would become the following C# type name:

System.Collections.Generic.Dictionary<System.String, MyNamespace.MyClass>

My regular expression needs to work regardless of the number of type parameters there are in the generic type. I've written an expression that successfully captures the generic type and its type parameters into two named groups:

^(?<GenericType>.+)`\d\[(?:\[?(?<GenericTypeParam>\S*),[^\]]+\]?,?)+\]$

Now I need to write the replace expression that generates the C# type name. But because there can be more than one capture in the "GenericTypeParam" group, I need to be able to refer to a variable number of captures in my replace expression. Here is the replace expression I have right now:

${GenericType}<${GenericTypeParam}>

But because it references the "GenericTypeParam" group by name, it gets the group value, which is the value of the last capture in the group. So, the output of this replace expression is:

System.Collections.Generic.Dictionary<MyNamespace.MyClass>

So my output string only contains the last capture in the group. Is there any way to access the other captures in the replace expression?

A: 

I don't think you can do this with regex replace. I think you'll have to loop thru the matches programatically, instead of extracting them with a replace expression. Something like (untested!):

List<string> types = new List<string>();
Match m;
for (m = reg.Match(GenericTypeParam); m.Success; m = m.NextMatch()) {
    types.Add( m.Groups["GenericTypeParam"].Value ); 
}

and then concatenate the list into the generic type param.

Val