У меня есть эти типовые строки:
"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, я хочу извлечь основной тип, его общий тип 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"
Есть ли регулярное выражение, которое может это сделать?
вы можете сделать это с помощью этого шаблона:
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)
и управлять, если группа существует в последнем совпадении.
"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]]"
с последним примером: "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]]"
- (изменен обратный тик с апострофом из-за синтаксического анализа SO), он останавливается на втором типе - ImaginaryType
, так как он не предшествует любому запятая ...
^(first-group-expression (second-group-expression))$
.