我制作了一个应用程序,旨在使用正则表列表准备翻译文件。
它使用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美元)
知道为什么会这样吗?
答案 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