如何在正则表达式中找到一个重叠或包含另一个时的所有匹配项

本文关键字:另一个 包含 重叠 一个 正则表达式 | 更新日期: 2023-09-27 18:22:33

Regex中的Overlapping matches中提出了如何在每个匹配可能重叠时找到它们的问题。然而,据我所见,那里的答案并没有涵盖更普遍的情况。

我们如何找到所有以"a"开头、以"z"结尾的子字符串?例如,给定"akzzaz",它应该找到"akz""akzz""az""akzzaz"

由于可能有不止一个匹配从同一位置开始("akz""akzz"),也可能有超过一个匹配在同一位置结束("az""akzzaz"),我看不出使用先行或后向有何帮助,如在上述链接中所述。(此外,请记住,在一般情况下,"a""z"可能是更复杂的正则表达式)

我使用C#,所以,如果重要的话,拥有任何特定于.Net正则表达式的功能都是可以的。

如何在正则表达式中找到一个重叠或包含另一个时的所有匹配项

正则表达式设计用于一次查找一个匹配项。即使是全局匹配操作也只是重复应用相同的正则表达式,每个正则表达式都从目标字符串中上一个匹配的末尾开始。所以不,正则表达式不能以这种方式找到所有匹配项。

我会坚持说,我不相信你甚至可以用正则表达式找到"akzzaz中所有以‘a’开头的字符串"。/(a.*)/g将查找整个字符串,而/(a.*?)/g仅查找两次"a"。

我编写代码的方式是定位所有的"a",并从那里到字符串末尾搜索每个子字符串以查找所有的"z"。因此,在"akzzaz"answers"az"中搜索"z",并给出"akz"、"akzz"、"ak zzaz"answers"az"。这是一件相当简单的事情,但对于regex来说不是一项工作,除非实际的"a"answers"z"标记很复杂。

对于您当前的问题,string.startwith和string.endwith会做得更好。正则表达式并不一定在所有情况下都更快。

试试这个正则表达式

a[akz]+z - in case a, k and z are the only characters
a[a-z]+z - in case of any alphabet

我认为值得注意的是,regex实际上有一种方法可以同时返回多个匹配项。虽然这不能回答你的问题,但我认为对于其他可能遇到类似情况的人来说,这将是一个很好的地方。例如,下面的正则表达式将返回具有单个匹配项的字符串的所有正确子字符串,并将它们放在不同的捕获组中:

(?=(''w+))。

此正则表达式在零宽度断言中使用捕获组,对于位置i处的每个匹配(每个字符),捕获组是长度为n-i的子字符串
对于正则表达式方法来说,做任何需要regex引擎在匹配后保持在同一位置的事情都可能是过分的。