2013-06-13 5 views
1

У меня есть следующий текст:Получить первое вхождение матча в Regex

«кошка лев собаки мышь»

И я ищу «собаку» или «мышь» с помощью регулярных выражений:

Regex regex = new Regex(@"dog|mouse"); 

Способ, которым Regex в C# ведет себя, состоит в том, что он сначала ищет весь путь для слова dog. Если он находит совпадение, он останавливается. Как заставить его остановиться после обнаружения первого появления какого-либо из моих слов в регулярном выражении, то есть остановиться после «cat», как это происходит первым?

Должен ли я делать несколько поисков регулярных выражений и соответствовать индексам результатов? Или можно указать его в выражении регулярного выражения?

+1

* означает остановку после «кошки», поскольку это происходит первым? *, Но ваше регулярное выражение - 'собака | мышь'? – aiapatag

+2

Это не «первый поиск собаки». Если ваш текст был «собакой мыши», мышь будет сопоставлена ​​(первая), независимо от того, что занимает второе место в регулярном выражении. Он ищет все выражение слева. –

+0

@NicholasW Просто проверил себя, и вы правы ^^ – Rawling

ответ

0

способ сделать это, чтобы использовать ленивый квантор dotall вариант:

Regex regex = new Regex(@"^.*?\b(?>dog|mouse)\b"); 

Другой способ сделать это;

Regex regex = new Regex(@"^(?>[^dm]*+|d++(?!og\b)|m++(?!ouse\b))*\b(?>dog|mouse)\b"); 

длиннее, но более эффективно. Идея состоит в том, чтобы избежать ленивого квантификатора, который является медленным, потому что он проверяет каждый персонаж, чтобы увидеть, что следует. Здесь я описать начале как «все, что не является d или m или какой-либо d не следует og или какой-либо m не следует ouse ноль или более раз.

(?>..) представляет собой атомную группу, это, чтобы избежать этого движок регулярных выражений отступаться, это своего рода «все или ничего», подробную информацию here

++ является possessive quantifier, что избежать откатывается тоже.

4

Нет, вы не правы.

Regex regex = new Regex(@"dog|mouse"); 

и

Regex regex = new Regex(@"mouse|dog"); 

как найти слово «собака», даже тогда, когда, как во втором случае слово «мышь» является первым в чередовании.

Совпадение по-разному, чем описано. Регулярное выражение будет проверяться на первом символе, если оно может соответствовать первой альтернативе, если это не соответствует, не будет продолжаться до второго символа, он попробует второй вариант.

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

Regex regex = new Regex(@"Foo|Foobar"); 

это никогда не будет соответствовать слову «Foobar», так как даже при наличии Foobar в тексте он совпадает с первой альтернативой «Foo».

Чтобы избежать этих проблем, заказать его с длиной короткого

Regex regex = new Regex(@"Foobar|Foo"); 

это будет пытаться соответствовать «Foobar» на «Foo», и когда он узнает, что нет «б» после, он пробует вторая альтернатива и успешно соответствует «Foo».

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