获取Regex中第一个匹配项
本文关键字:第一个 Regex 获取 | 更新日期: 2023-09-27 18:18:17
我有以下文本:
"猫狗老鼠狮子"
和我搜索"狗"或"鼠标"使用regex:
Regex regex = new Regex(@"dog|mouse");
c#中的Regex的行为方式是它首先搜索单词dog。如果找到匹配,它就停止。我如何使它在找到正则表达式中任何单词的第一次出现后停止,意思是在"cat"之后停止,因为它首先出现?
我是否必须进行多个正则表达式搜索并匹配结果的索引?或者可以在正则表达式中指定它?
你错了。
Regex regex = new Regex(@"dog|mouse");
和
Regex regex = new Regex(@"mouse|dog");
两者都能找到单词"dog",即使像在第二种情况下,单词"mouse"是交替出现的第一个。
匹配行为与您描述的不同。regex将在第一个字符处检查它是否可以匹配第一个替代,如果不匹配,它将不会继续到第二个字符,它将尝试第二个替代。
但是,替换的顺序在另一方面也很重要。当你有相同开头的备选项,而你将它们从短到长排序时,你会遇到问题,例如
Regex regex = new Regex(@"Foo|Foobar");
这将永远不会匹配单词"Foobar",因为即使文本中有Foobar,它也会匹配第一个替代"Foo"。
为了避免这些问题,从长到短排序
Regex regex = new Regex(@"Foobar|Foo");
this将尝试匹配"Foo"上的"Foobar",当它识别到后面没有"b"时,它尝试第二个替代并成功匹配"Foo"。
一种方法是使用带有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
零次或以上的内容。
(?>..)
是一个原子组,这是为了避免regex引擎回溯,它是一种"全有或全无",更多信息在这里
++
是一个所有格量词,可以避免回溯。