Как получить повторяющиеся группы, которые вложены в другую группу с помощью регулярных выражений?

1

У меня есть эти типовые строки:

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

Есть ли регулярное выражение, которое может это сделать?

  • 0
    Да. Вы можете использовать вложенные группы, например, так: ^(first-group-expression (second-group-expression))$ .
Теги:

1 ответ

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) и управлять, если группа существует в последнем совпадении.

  • 0
    Вау! отличный ответ :-), но он все еще не "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 , так как он не предшествует любому запятая ...
  • 0
    Ага, я потел над этим в течение некоторого времени, и этот Динамический Дуэт выбивает его из парка. Пытаюсь поймать третий случай Тала :)
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню