2014-12-04 29 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