如何使用正则表达式在另一个组中嵌套重复组?

时间:2014-10-07 11:01:23

标签: c# .net regex

我有这些示例类型字符串:

"System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

"System.Collections.IEnumerable"

"System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

"Whatever`3[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[ImaginaryType],[System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

使用正则表达式,我想提取main-type,它的泛型类型count以及所有泛型类型本身,所以对于上面的四个例子,我相应地“捕获”这些元素:

"System.Collections.Generic.IEnumerable"
    1
    "System.String"

"System.Collections.IEnumerable"
    0

"System.Collections.Generic.Dictionary"
    2
    "System.Int32"
    "System.Type"

"Whatever"
    3
    "System.Int32"
    "ImaginaryType"
    "System.Type"

是否有正则表达式可以做到这一点?

1 个答案:

答案 0 :(得分:2)

你可以用这种模式做到:

string pattern = @"
(?:   # two possible entry points
    \G(?!\A)       # contigous to the precedent match
  |                # OR
    \A             # at the start of the string
    (?<main> [^`]+ )  ` (?<number> [0-9]+ ) \[
)

\[ (?<type> [^],]+ ) # generic type
[^]]* ]              # all until the next closing square bracket
(?: , | ]\z )

| \A (?<main> [^`]+ ) # or a main-type without generic types
";

RegexOptions options = RegexOptions.IgnorePatternWhitespace;

foreach (Match match in Regex.Matches(input, pattern, options)) { ...

如果您计划多次使用该模式,最好一次性编译它。 请注意,您可以使用此变体来减少正则表达式引擎的工作:

string pattern = @"
  \G(?!\A) \[
  (?<type> [^],]+ )
  [^]]* ] (?: , | ]\z )
|
  \A
  (?<main> [^`]+ ) 
  (?:
      ` (?<number> [0-9]+ )
      \[{2}
      (?<type> [^],]+ )
      [^]]* ]
      (?: , | ]\z )
    |
      \z
  )";

如果您想确保已到达字符串的结尾,可以将]\z替换为(?<endcheck>]\z),并控制该组是否存在于最后一个匹配项中。