C# 如何使用regex获取嵌套在另一个组中的重复组?

C# 如何使用regex获取嵌套在另一个组中的重复组?,c#,.net,regex,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,

我有以下示例类型字符串:

"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]]"
使用regex,我想提取主类型、它的泛型类型计数以及所有泛型类型本身,因此对于上面的四个示例,我相应地“捕获”了这些元素:

"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"

有一个正则表达式可以做到这一点吗?

您可以使用以下模式:

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)) { ...
字符串模式=@”
(?:#两个可能的入口点
\G(?!\A)#继续进行先例比赛
|#或
\A在字符串的开头
(? [^`]+ )  ` (? [0-9]+ ) \[
)
\[(?[^],]+)#泛型
[^]]*]#直到下一个结束方括号
(?:,|]\z)
|\A(?[^`]+)#或没有泛型类型的主类型
";
RegexOptions options=RegexOptions.IgnorePatternWhitespace;
foreach(Regex.Matches中的Match(输入、模式、选项)){。。。
如果您多次使用该模式,最好一次性编译它。 请注意,您可以使用此变体来减少正则表达式引擎的工作量:

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

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

是。可以使用嵌套组,如:
^(第一个组表达式(第二个组表达式))$
.Wow!回答很好:-)但最后一个例子仍然没有提到:
“不管是什么,[[System.Int32,mscorlib,Version=4.0.0.0,Culture=中立,PublicKeyToken=b77a5c561934e089],[ImaginaryType],[System.Type,mscorlib,Version=4.0.0.0,Culture=中立,PublicKeyToken=b77a561934e089]”
-(由于SO的解析,将背面的勾号改为撇号)它停在第二种类型上-
ImaginaryType
,因为它不在任何逗号之前…唉,我已经为此流了一段时间的汗,这对充满活力的组合将它击出了公园。试图抓住第三种情况下的Tal:)@Tal:您只需要在否定字符类中添加结束方括号,请参见我的编辑。