Regex.Replace似乎不适用于反向引用

时间:2009-09-18 14:48:29

标签: c# regex

我制作了一个应用程序,旨在使用正则表列表准备翻译文件。

它使用Regex.Replace在文件上运行每个正则表达式。还有一个检查器模块,允许用户查看列表中每个正则表达式的匹配项。

它运行良好,除非正则表达式包含反向引用,Regex.Replace不会替换任何内容,但是检查器会正确显示匹配项(因此我知道正则表达式是有效的并且与它应该匹配的内容)。

sSrcRtf = Regex.Replace(sSrcRtf, sTag, sTaggedTag,
  RegexOptions.Compiled | RegexOptions.Singleline);

sSrcRtf包含页面的RTF代码。 sTag包含括号之间的正则表达式。 sTaggedTag包含由标记格式代码包围的$ 1。

举个例子:

sSrcRtf = Regex.Replace("the little dog", "((e).*?\1)", "$1", 
  RegexOptions.Compiled | RegexOptions.Singleline);

不起作用。但是

sSrcRtf = Regex.Replace("the little dog", "((e).*?e)", "$1", 
  RegexOptions.Compiled | RegexOptions.Singleline);

一样。 (当然,有一些RTF代码大约1美元)

知道为什么会这样吗?

3 个答案:

答案 0 :(得分:2)

你在技术上有两个匹配组,外括号和内括号。为什么不尝试将内部集合作为第二次捕获来解决,例如:

((e).*?\2)

你的解析器可能认为外部捕获是\ 1,从内部反向引用它没有多大意义。

另请注意,您的更换将不会执行任何操作,因为您要求更换与自身匹配的部分。我不确定你的预期行为是什么,但是如果你试图提取匹配并丢弃其余的字符串,你需要类似的东西:

.*((e).*?\2).*

答案 1 :(得分:0)

您正在使用对您引用的群组内的群组的引用。

"((e).*?\1)" // first capturing group
"(e)" // second capturing group

我不是100%肯定,但我认为你不能从该组中引用一个组。对于初学者来说,你期望反向引用匹配什么,因为它还没有完成呢?

答案 2 :(得分:0)

正如其他人所提到的,还有一些其他群体被捕获。您的替换品没有引用正确的替代品。

您当前的正则表达式应该重写为(选项省略):

Regex.Replace("the little dog", @"((e).*?\2)", "$2")
// or
Regex.Replace("the little dog", @"(e).*?\1", "$1")

这是另一个匹配双字的示例,表示哪些反向引用有效:

Regex.Replace("the the little dog", @"\b(\w+)\s+\1\b", "$1")  // good
Regex.Replace("the the little dog", @"\b((\w+)\s+\2)\b", "$1") // no good
Regex.Replace("the the little dog", @"\b((\w+)\s+\2)\b", "$2") // good