2014-12-04 64 views
2

如果我有一個不同的正則表達式可能看起來像以下任何模式是:如何僅對一個命名捕獲組執行Regex替換?

(.{2})(?<somedigit>\d+)(.{5}) 
(?<somedigit>\d+)(.{7}) 
(.{1})(?<somedigit>\d+) 

,我想與任何數量的更換somedigit捕獲組,並保留一切不變,怎麼會有我這樣做(用C#或Java說)?

例如,說我有這樣的文字:

QB2-G456 

我用這個表達式:

(.{2})(?<somedigit>\d+)(.{5}) 

與之相匹配的,說我想用35來替換somedigit,得到這個最終結果:

QB35-G456 

我知道我可以使用這個替換文本︰

${1}35${2} 

但我的問題的根源是,我不知道我的正則表達式的前期格式。所以我不能爲我不想改變的文本對捕獲組引用進行硬編碼,因爲可能會有不同的變化。

由於可能存在多個數字,我不能只是將\ d +替換爲我不知道數字是在開始還是結束還是中間,以及其他數字是否在文本中進一步存在。

理想我希望這樣的事情:

new Regex("(.{2})(?<somedigit>\d+)(.{5})").ReplaceCaptureGroup("QB2-G456", "somedigit", "35") 

,並擁有一切通過未修改除了被替換的somedigit捕獲組。

我搜索了類似的問題,只找到解決方案,正確和已知的正則表達式,如上面已經解釋。

+0

爲什麼不與其他組轉換成非捕獲('(?:XXXX)',而不是'(XXXX)')?那麼你只有一件事可以替代呢? – 2014-12-04 22:49:42

+0

當然,但我會如何編寫該代碼?我需要包括其他文本以確定我想要替換的捕獲組的位置,但是如果我這樣做,那麼整個比賽肯定會被替換?也許是兩個班輪的例子? – pwnell 2014-12-04 23:00:52

+0

你應該用你正在使用的語言來標記它。 – jpmc26 2014-12-04 23:03:32

回答

1

這裏是你如何在C#中做到這一點:

var str1 = "QB2-G456"; 
var rx1 = new Regex(@"(.{2})(?<somedigit>\d+)(.{5})"); 
var res = rx1.Replace(str1, m => m.Value.Replace(m.Groups["somedigit"].Value, "35")); 
// Result: QB35-G35456 

這將替換字符串內的「somedigit」組內容全部出現(即QB2-G2456會變成QB35-G35456)。要解決此問題,使用Regex.Replace(input, regex, repl, numOfReplacements)或此方法:

public string ReplaceOnceAtIndex(string text, string search, string replace, int index) 
{ 
    if (index < 0) 
     return text; 
    return text.Substring(0, index) + replace + text.Substring(index + search.Length); 
} 
// ... And thenin the caller ... 
var res2 = rx1.Replace(str1, m => 
ReplaceOnceAtIndex(m.Value, m.Groups["somedigit"].Value, "35", m.Groups["somedigit"].Index)); 
// Result: QB35-G2456