反向引用是否需要在它们引用的组之后?

2023-12-01

在运行一些测试时这个答案,我注意到以下意外行为。这将删除所有出现的<tag>在第一个之后:

var input = "<text><text>extra<words><text><words><something>";
Regex.Replace(input, @"(<[^>]+>)(?<=\1.*\1)", "");
// <text>extra<words><something>

但这不会:

Regex.Replace(input, @"(?<=\1.*)(<[^>]+>)", "");
// <text><text>extra<words><text><words><something>

同样,这将删除所有出现的<tag>在最后一个之前:

Regex.Replace(input, @"(<[^>]+>)(?=.*\1)", "");
// extra<text><words><something>

但这不会:

Regex.Replace(input, @"(?=\1.*\1)(<[^>]+>)", "");
// <text><text>extra<words><text><words><something>

所以这让我思考......

.NET正则表达式引擎中,是否需要出现反向引用after它引用的组?或者这些模式是否还有其他原因导致它们不起作用?


你的问题也让我思考,所以我进行了一些测试正则表达式好友令我惊讶的是第二个正则表达式(?<=\1.*)(<[^>]+>)你说的不起作用实际上起作用了,其他的也完全按照你说的那样工作。然后我尝试了同样的表达- 第二个 -在 C# 代码中,但它不像你发生的那样工作。

这让我很困惑,然后我注意到我的 RegexBuddy 版本可以追溯到 2008 年,所以 .NET 引擎的工作方式肯定有一些变化,但这揭示了一个我认为合理的事实,似乎在 2008 年之前的回溯在表达式的其余部分匹配后进行评估。我觉得这种行为对于lookbehinds来说是可以接受的,因为你需要先匹配一些东西,然后再看后面才能匹配它之前的东西。

尽管如此,现在的引擎似乎在遇到环视时会评估环视,我可以通过使用以下表达式找到这一点,这与您的情况相反:

(?<=(\w))\1

正如您所看到的,我在正则表达式内捕获了一个单词字符并在其外部引用了它。我在绳子上测试了这个hello它在第二个匹配l字符符合预期,这证明在尝试匹配表达式的其余部分之前执行了lookbehind。

结论:是的,后向引用需要出现在它引用的组之后,否则它将没有匹配语义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

反向引用是否需要在它们引用的组之后? 的相关文章

随机推荐