获取Regex中第一个匹配项

本文关键字:第一个 Regex 获取 | 更新日期: 2023-09-27 18:18:17

我有以下文本:

"猫狗老鼠狮子"

和我搜索"狗"或"鼠标"使用regex:

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

c#中的Regex的行为方式是它首先搜索单词dog。如果找到匹配,它就停止。我如何使它在找到正则表达式中任何单词的第一次出现后停止,意思是在"cat"之后停止,因为它首先出现?

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

获取Regex中第一个匹配项

你错了。

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");

它更长,但更有效。这个想法是为了避免懒惰量词,因为它会对每个字符进行测试,看看接下来是什么。这里我将开头描述为"所有不是dm或某些d不跟随og或某些m不跟随ouse零次或以上的内容。

(?>..)是一个原子组,这是为了避免regex引擎回溯,它是一种"全有或全无",更多信息在这里

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