2009-09-18 63 views
1

我製作了一個應用程序,用於使用正則表列準備翻譯文件。Regex.Replace似乎不適用於反向引用

它使用Regex.Replace在文件上運行每個正則表達式。還有一個檢查器模塊,允許用戶查看列表上每個正則表達式的匹配。

它工作得很好,除非正則表達式包含一個back-reference,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美元左右)

任何想法爲什麼這是?

回答

2

你在技術上有兩個匹配組,外部和內部括號。你爲什麼不嘗試解決內設定爲第二擷取,例如:

((e).*?\2) 

你的解析器可能認爲外捕捉\ 1,它並沒有太大的意義,從自身內部的反向引用它。

另請注意,您的替換件不會執行任何操作,因爲您要求替換與自己匹配的部分。我不知道你的意圖的行爲是什麼,但如果你想只提取了比賽並丟棄字符串的其餘部分,你想要的東西,如:

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

感謝。我沒有意識到,外面的括號會在本身內計算回參考。對於替換,這只是一個例子。在實際的代碼中,$ 1被一些RTF代碼所包圍,這些代碼根據所需樣式的類型而生成。我沒有發佈整件事情,因爲它有點長,可能會分散眼前的問題。 – Sylverdrag

0

您正在使用對您引用的組內的組的引用。

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

我不是100%確定的,但我不認爲你可以從該組內引用一個組。對於初學者來說,你會期望反向引用匹配,因爲它甚至還沒有完成?

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 
相關問題