在Regex中首次出现匹配

时间:2013-06-13 11:08:17

标签: c# regex

我有以下文字:

“猫狗老鼠狮子”

我使用正则表达式搜索“dog”或“mouse”:

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

C#中Regex的表现方式是它首先搜索单词dog。如果找到匹配,则停止。如何在正则表达式中找到我的任何单词的第一次出现后如何停止,这意味着在“cat”之后停止,因为这首先出现?

我是否必须进行多次正则表达式搜索并匹配调查结果的索引?或者是否可以在正则表达式中指定它?

2 个答案:

答案 0 :(得分: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");

这将尝试匹配“Foo”上的“Foobar”,当它识别时,没有“b”跟随,它尝试第二种选择并成功匹配“Foo”。

答案 1 :(得分: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");

它更长但效率更高。这个想法是避免懒惰的量词,因为它测试每个字符以查看后面的内容。在这里,我将开头描述为“所有不是dm或某些d未跟随og或某些m未跟随ouse {1}}零次或多次。

(?>..)是一个原子组,这是为了避免正则表达式引擎回溯,它是一种“全有或全无”,更多信息here

++是一个possessive quantifier,可以避免回溯。