2013-09-10 5 views
1

Я пытаюсь реализовать регулярное выражение, которое имеет возможность назначить одно и то же ключевое слово или комбинацию ключевых слов одной или нескольким именованным группам.Regex, назначая несколько групп ключевому слову

Например, я хочу, чтобы соответствовать ('АА' и 'BB') OR 'CC' и назначить 'АА' и 'ВВ' к группе < 1> и 'CC', чтобы группы < 2>.

Также я могу иметь запрос типа («АА» и «BB») OR «аа» и я хочу «АА» и «ВВ», чтобы быть в группе < 1> и в то же время «аа 'быть в группе < 2>.

// Works to get 'aa' everywhere but cannot find a way to add 'bb' to the group<1> 
(?=(?:\s+|^)(?<1>aa)(?:\s+|$)) 

EDIT:

Input Example : bb is nice but not without the missingaa 
Output : Does not Validate, Group<1> is null | Group<2> is null 

-

Input Example : bb is nice as well as aa 
Output : Validate, Group<1> : bb is nice as well as aa | Group<2> is null 

-

Input Example : bb is nice but not without the missingaa or cc 
Output : Validate, Group<1> is null | Group<2> is cc 

-

Input Example : bb is nice as well as aa or cc 
Output : Validate, Group<1> is bb is nice as well as aa | Group<2> is cc 

Я знаю, что группировка может быть сложной, но я ищу группу < 1> которая не является нулевой, если существуют aa и bb.

Как добиться такого поведения?

+0

Можете ли вы привести пример ввода и желаемого вывода, пожалуйста? Проблема заключается в вводе imo. С чем должна отвечать первая группа? А когда должна совпасть вторая группа? – EverythingRightPlace

+0

Какой двигатель вы используете, который позволяет цифру для первого символа имени группы? (? <1> ,,),,) – sln

+0

Я использую .NET C# 4.0/4.5 – user2465083

ответ

0

В качестве ориентира, с большинством двигателей регулярных выражений, групповые совпадения не накапливаются как массив. Dot-Net является исключением, которое может сделать это (коллекции).

Приносим извинения, что вы были правы, это требует чередования.
Однако вам нужно заставить найти первый OR c. Это делается с условным просмотром. Удачи!

# ^.*?(?:(?:(?<grp1>(?:\baa\b.*?\bbb\b|\bbb\b.*?\baa\b))(?(?=.*\b(?:cc|aa)\b).*(?<grp2>(?:\bcc\b|\baa\b))|))|(?<grp2>\b(?:cc|aa)\b)) 

^
    .*? 
    (?: 
     (?:       # Force find a AND b, OR c 
      (?<grp1> 
       (?: 
         \b aa \b .*? \b bb \b 
        | \b bb \b .*? \b aa \b 
       ) 
      ) 
      (?(?=     # conditional assertion, force to find 
       .* 
       \b (?: cc | aa ) \b 
      ) 
       .* 
       (?<grp2> 
         \b (?: cc | aa ) \b 
       ) 
       | 
      ) 
     ) 
    | 
     (?<grp2>    # Else, forcc find OR c 
      \b (?: cc | aa ) \b 
     ) 
) 

Edit: Это будет соответствовать (аа сс), (бб)
Но берегитесь, тем больше перестановок, тем более сложным. И это ведет по дорогам к утверждениям, флагам, состояниям, все из которых замедляют работу и делают обслуживание более жестким.

# ^.*?(?:(?:(?<grp1>(?:\baa\b(?:(?!cc).)*?\bbb\b|\baa\b(?:(?!bb).)*?\bcc\b|\bbb\b(?:(?!cc).)*?\baa\b|\bbb\b(?:(?!aa).)*?\bcc\b))(?(?=.*\b(?:aa|bb|cc)\b).*(?<grp2>\b(?:aa|bb|cc)\b)|))|(?<grp2>\b(?:cc|aa)\b)) 

^ 
.*? 
(?: 
     # Force find: (aa bb), (cc) 
     #    (aa cc), (bb) 
     #    (bb aa), (cc) 
     #    (bb cc), (aa) 
     (?: 
      (?<grp1>          # GROUP1 
       (?: 
        \b aa \b (?:(?!cc).)*? \b bb \b 
        | 
        \b aa \b (?:(?!bb).)*? \b cc \b 
        | 
        \b bb \b (?:(?!cc).)*? \b aa \b 
        | 
        \b bb \b (?:(?!aa).)*? \b cc \b 
       ) 
      ) 

      (?(?=  # Conditional assertion, find (aa), (bb), (cc) 
       .* 
       \b (?: aa | bb | cc) \b 
      ) 
       # The condition is true, so consume it 
       .* 
       (?<grp2>        # GROUP2 
        \b (?: aa | bb | cc) \b 
       ) 
      | # The condition is false, match nothing 
      ) 

    ) 
    | 
     # Or, 
     # Force find: (), (aa) 
     #    (), (bb) 
     #    (), (cc) 

     (?<grp2>      # GROUP2 
      \b (?: aa | bb | cc) \b 
    ) 
) 
+0

Здравствуйте, спасибо за ваш ответ. На самом деле я использую .NET, но я не думаю, что мне нужно иметь рекурсивное регулярное выражение. Не могли бы вы проверить с примерами, которые я представил? – user2465083

+0

Не могли бы вы рассказать мне, если вы найдете лучшее решение, чем это: (? <1> aa. * Bb | bb. * Aa) | (? <2> cc), поскольку я хотел бы добавить, вероятно, больше членов, спасибо только 2 в group1. Также, если я делаю (? <1> aa. * Bb | bb. * Aa) | (? <2> aa) в группе «aa bb» <1> будет содержать «aa bb», но группа <2> не будет содержать «aa», и это важно мне. – user2465083

+0

Благодарим вас за редактирование. Это хорошо работает для случая, такого как «aa bb cc». Теперь одна из сложностей регулярного выражения заключалась в том, что я могу иметь «bb aa», так что для этого требуется префикс (? =) Для «aa» и «bb». В настоящее время «bb aa» невозможно захватить. Кроме того, заменив «cc» на «aa» # (? . * \ Baa \ b. * \ Bbb \ b)? (? . * \ B (?: Aa) \ b)), "aa bb" является только в , а не в обоих из них. – user2465083

Смежные вопросы