用对特定捕获组的操作替换regex的所有匹配

本文关键字:regex 替换 操作 | 更新日期: 2023-09-27 18:01:58

我有不同的Xml字符串,可以包含以下格式的一个或多个部分:

<ns1:AcctId>47862656</ns1:AcctId>

中间的值可以改变。我想用一个被操纵的值(从BBAN到IBAN)替换这个<ns:1:AcctId>元素的所有出现。

我在XMLModel类中使用属性Xml (xml字符串)进行了以下方法:

string regexString = "(<ns1:AcctId>)(?<AcctId>.*?)(</ns1:AcctId>)";
Regex regex = new Regex(regexString);
Match match = regex.Match(Xml);
string AcctId = match.Groups["AcctId"].Value;
string IBANizedAcctId = IBANHelper.ConvertBBANToIBAN(AcctId);
Xml = Regex.Replace(Xml, regexString, string.Format("$1{0}$3", IBANizedAcctId));

这里的想法是regexString有三个捕获组,我将中间值(帐号)替换为转换为IBAN的帐号。

不幸的是,这段代码不起作用:1)它确实捕获了AcctId的值,但它没有正确地替换它,因为它失去了最后的</ns1:AcctId>部分。2)将匹配的所有出现替换为第一个捕获的值,同时应该将每个出现替换为捕获的特定值。

在c#中有办法做到这一点吗?如果有的话,有人能给我一些建议吗?

用对特定捕获组的操作替换regex的所有匹配

您不应该使用regex来操作XML,它们不是合适的工具,而且并不总是有效。例如,XML文件可以使用ns1以外的名称空间前缀,映射到相同的名称空间,并且在语义上是等价的,但是您的regex将不再工作。

你应该使用XML解析器;最容易使用的是Linq to XML:

var doc = XDocument.Parse(Xml);
var ns1 = XNamespace.Get("http://TheNamespaceMappedToTheNs1Prefix");
var elements = doc.Descendants(ns1 + "AcctId");
foreach (var e in elements)
{
    e.Value = IBANHelper.ConvertBBANToIBAN(e.Value); 
}
Xml = doc.ToString();

除常规外,不要使用正则表达式来操作XML。

string regex = "(?<=<ns1:AcctId>).*?(?=</ns1:AcctId>)";
Xml = Regex.Replace(Xml, regex, delegate(Match m) {
                           return IBANHelper.ConvertBBANToIBAN(m.Value);
                         });

使用正向查找和向后查找,以便匹配的只是帐号,然后重载到Regex。