如何仅在一个命名的捕获组上执行正则表达式替换?

时间:2014-12-04 22:40:45

标签: java c# 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 捕获组之外,一切都未经修改。

我搜索了类似的问题,并且只找到了正则表达式修复和已知的解决方案,如上所述。

1 个答案:

答案 0 :(得分: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