2014-09-01 4 views
1

Я пытаюсь извлечь некоторые альфаномические выражения из более длинного слова в C#, используя регулярные выражения. Например, у меня есть слово «FooNo12Bee». Я использую следующее регулярный код выражения, которое возвращает мне два матча, «NO12» и «Нет» в качестве результатов:Weird Regex поведение в C#

alfaNumericWord = "FooNo12Bee"; 
Match m = Regex.Match(alfaNumericWord, @"(No|Num)\d{1,3}"); 

Если я использую следующее выражение, без paranthesis и без каких-либо альтернатив «Нет» это работает так, как я ожидал, он возвращает только «NO12»:

alfaNumericWord = "FooNo12Bee"; 
Match m = Regex.Match(alfaNumericWord, @"No\d{1,3}"); 

в чем разница между этими двумя выражениями, почему с использованием результатов paranthesis в резервируемой результат для «Нет»?

+1

[Groups] (http://www.regular-expressions.info/brackets.html) - это не * излишней * вы явно попросили его записать его – CodingIntrigue

ответ

6

Скобка в регулярном выражении - группы захвата; что означает, что между парном будет захвачен и сохранен как группа захвата.

Если вы не хотите группу захвата, но все же нуждаетесь в группе для чередования, используйте вместо нее группу без захвата; поставив ?: после первого Paren:

Match m = Regex.Match(alfaNumericWord, @"(?:No|Num)\d{1,3}"); 

Обычно, если вы не хотите, чтобы изменить регулярное выражение для какой-то причине, вы можете просто получить группу 0 от матча, чтобы получить только весь матч (и, таким образом, игнорировать любые группы захвата); в вашем случае, используя m.Groups[0].Value.

Наконец, вы можете повысить эффективность регулярных выражений выемки с помощью:

Match m = Regex.Match(alfaNumericWord, @"N(?:o|um)\d{1,3}"); 
+0

А я вижу, я не знал, что использование paranthesis имеет явное задание для захвата подгрупп, я использовал их только для того, чтобы захватывать альтернативные слова. Есть ли другой способ поиска альтернативных слов без использования paranthesis? –

+0

@ UfukCanBiçici Вы можете использовать более длинную альтернативу: 'No \ d {1,3} | Num \ d {1,3}', но ... это слишком повторяющийся, я считаю :) Иначе нет. – Jerry

1

Я не могу объяснить, как они это называют, но это потому, что создание круглых скобок вокруг него создает новую группу. это хорошо объясняется here

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

Регулятор (значение)? соответствует Set или SetValue. В первом случае первая (и только) группа захвата остается пустой. Во втором случае первая группа захвата соответствует значению.

1

Это потому, что круглые скобки создают группу. Вы можете удалить группу с ?: так Regex.Match(alfaNumericWord, @"(?:No|Num)\d{1,3}");