我有以下文字:
“猫狗老鼠狮子”
我使用正则表达式搜索“dog”或“mouse”:
Regex regex = new Regex(@"dog|mouse");
C#中Regex的表现方式是它首先搜索单词dog。如果找到匹配,则停止。如何在正则表达式中找到我的任何单词的第一次出现后如何停止,这意味着在“cat”之后停止,因为这首先出现?
我是否必须进行多次正则表达式搜索并匹配调查结果的索引?或者是否可以在正则表达式中指定它?
答案 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");
它更长但效率更高。这个想法是避免懒惰的量词,因为它测试每个字符以查看后面的内容。在这里,我将开头描述为“所有不是d
或m
或某些d
未跟随og
或某些m
未跟随ouse
{1}}零次或多次。
(?>..)
是一个原子组,这是为了避免正则表达式引擎回溯,它是一种“全有或全无”,更多信息here
++
是一个possessive quantifier,可以避免回溯。