【发布时间】:2013-08-23 00:49:41
【问题描述】:
在为this answer 运行一些测试时,我注意到以下意外行为。这将删除第一个之后出现的所有<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 正则表达式引擎中,反向引用是否需要出现在它所引用的组之后?或者这些模式是否还有其他原因导致它们不起作用?
【问题讨论】:
-
从逻辑上讲,您需要先捕获某些内容,然后将其用作反向引用,否则递归正则表达式 like this one 将失败 :) PS:不仅在 .net 中,我认为在所有情况下都是如此口味。在php pcre中查看演示
-
@HamZa 谢谢,这是一个很好的观点。我会认为环视断言 可能 会有所不同,因为(据我所知)它们必须在字符串的匹配部分之后进行评估。换句话说,它必须先找到
<tag>,然后才能检查断言——但我对正则表达式的内部了解不多,所以我可能错了。另外,我想在大多数情况下,如果引擎的行为取决于评估它的顺序而不是它在模式中出现的顺序,那将会更令人惊讶。
标签: c# .net regex backreference