1

我有以下文字:

“猫狗老鼠狮子”

我使用正则表达式搜索“狗”或“鼠标”:

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

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

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

4

2 回答 2

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”。

于 2013-06-13T11:19:09.457 回答
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");

它更长但更有效。这个想法是避免延迟量词很慢,因为它会测试每个字符以查看后面的内容。在这里,我将开头描述为“所有不是 admOR 的东西,一些d不跟ogOR 一些m不跟ouse零次或多次。

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

++是一个所有格量词,也可以避免回溯。

于 2013-06-13T11:14:49.513 回答