繁体   English   中英

将正则表达式的所有匹配项替换为对特定捕获组的操作

[英]Replace all matches of regex with manipulation on specific capturing group

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

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

中间的值可以更改。 我想将这个<ns:1:AcctId>元素的所有出现都替换为可操纵的值(具体来说是从BBAN到IBAN)。

我已经在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#中有什么方法可以做到这一点? 如果是这样,有人可以给我一些如何做的指示吗? 任何帮助将不胜感激。

您不应该使用正则表达式来操作XML,它们不是用于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的重载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM