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

Posted

技术标签:

【中文标题】如何仅对一个命名捕获组执行正则表达式替换?【英文标题】:How to perform a Regex replacement on one named capture group only? 【发布时间】:2015-02-03 00:19:14 【问题描述】:

如果我有一个不同的正则表达式,它可能看起来像以下任何一种模式:

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

我想用任何数字替换 somedigit 捕获组,而其他所有内容都保持不变,我该怎么做(比如在 C# 或 Java 中)?

例如,假设我有这个文本:

QB2-G456

我使用这个正则表达式:

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

匹配它,并说我想用 35 替换 somedigit,以获得最终结果:

QB35-G456

我知道我可以使用这个替换文本:

$135$2

但我的问题的根源是我不知道我的正则表达式的格式。所以我不能硬编码我不想更改的文本的捕获组引用,因为可能会有不同的变化。

由于可能存在多个数字,我不能只替换 \d+,因为我不知道数字是在开头还是结尾或中间,以及文本中是否还有其他数字。

理想情况下,我希望得到类似的东西:

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

除了被替换的 somedigit 捕获组之外,所有内容都未经修改地通过。

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

【问题讨论】:

为什么不将其他组转换为非捕获组((?:xxxx) 而不是(xxxx))?那你反正只有一件事要换? 当然可以,但是我将如何编写该代码?我需要包含其余文本以确定要替换的捕获组的位置,但是如果这样做,肯定会替换整个匹配项吗?也许是两个班轮的例子? 你应该用你正在使用的语言来标记它。 我希望能找到一个应用广泛的解决方案,可能是Java/C#/Perl/等等。 如果我对@JohnBus​​tos 的理解正确,一般来说:echo QB2-G456 | perl -ne 's/(.2)\d+(.5)/$135$2/g; print' 使用非捕获组产生QB35-G456 我会这样做:echo QB2-G456 | perl -ne 's/(?:.2)\d+(?:.5)/35/g; print' 产生35 但正如您所见只打印替换的文本,而不是其他文本。 【参考方案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

【讨论】:

以上是关于如何仅对一个命名捕获组执行正则表达式替换?的主要内容,如果未能解决你的问题,请参考以下文章

Java 正则表达式之捕获组

正则表达式中的命名捕获组

Python:使用JSON API链接通过正则表达式显示命名捕获组

正则表达式进阶

.Net 正则表达式用捕获组替换重复出现的模式

SQL查找和替换正则表达式捕获组限制?