用正则表达式替换字符串

本文关键字:字符串 替换 正则表达式 | 更新日期: 2023-09-27 18:28:46

我正在寻找一种方法来替换我称之为文档xml文件上的垃圾文本,用值替换

我有这个程序,它可以获取doc-xml来打印合同,用户只需要用doc-xml文件格式向程序提供一些参数,我的程序将用值替换这些参数

比方说,我有一块合同格式的

The Contract {@ContractNumber} specified to the contractor {@ContractorName}....

我的程序寻找用Contract值替换的参数{@ContractNumber}和{@ContractorName},我只是要求用户使用XML-DOC格式,但有时它编写的文件是这样的

<w:p w:rsidR="0094616E" w:rsidRDefault="00AC620A"><w:pPr><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t>{@</w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t>ContractorNumber</w:t></w:r>

有时它会做我真正希望的

<w:p w:rsidR="0094616E" w:rsidRDefault="0094616E"><w:pPr><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t>{@Value1}</w:t></w:r></w:p>

所以,我要找的是一个RegEx替换语句,在这里我可以清除在我的params({@)的打开字符和它的闭包(})之间可以找到的所有垃圾,这样它就可以找到我要用分配给它的值替换的整个单词

编辑1:

为了更简单地理解我的问题,我正在寻找的是一个ReGex,它将查找{@和后续}之间的所有内容,当它找到<>时,删除它们及其内的所有内容。因此,我最终拥有{@Param},而不是{@ <garbage/> Param <garbage/> }{@Param <garbage/> }{@Pa <garbage/> am}

编辑2:

到目前为止,最有用的正则表达式是这个

{.*?@.*?}

给我一个像这样的结果

{</w:t></w:r><w:r><w:t>@Contrato</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Obrigado</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Adquisicion</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Import</w:t></w:r><w:r><w:t>e</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Acreditado</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>ImporteLetras</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>O</w:t></w:r><w:r><w:t>ficio</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>FechaOficio</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Gracia</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>M</w:t></w:r><w:r><w:t>ensualidad-Gracia</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>ImporteMensualidad</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>I</w:t></w:r><w:r><w:t>mporteMensualidadLetra</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>D</w:t></w:r><w:r><w:t>ireccionAcreditada</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>EdoC</w:t></w:r><w:r><w:t>ivilAcreditado</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>CiudadOri</w:t></w:r><w:r><w:t>genAcredi</w:t></w:r><w:r><w:t>t</w:t></w:r><w:r><w:t>a</w:t></w:r><w:r><w:t>do</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>IFE</w:t></w:r><w:r><w:t>Acreditado</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Sexo</w:t></w:r><w:r><w:t>Acreditado}
{@</w:t></w:r><w:r><w:t>EdoCivilAval</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>CiudadOrigenAval</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>IFEAval</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>S</w:t></w:r><w:r><w:t>e</w:t></w:r><w:r><w:t>xoAval</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>NumeroAmortizacion</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>DireccionAval</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>ProgramaCredito</w:t></w:r><w:r><w:t>}
{@</w:t></w:r><w:r><w:t>Por</w:t></w:r><w:r><w:t>cComisionAper</w:t></w:r><w:r><w:t>tura</w:t></w:r><w:r><w:t>}

现在,我需要的是Regex删除所有这些字符之间的字符,似乎找不到删除这些字符的方法:S

用正则表达式替换字符串

您提供的第一个XML代码块不包含}字符,因此它已经破坏了您的先决条件。然而,如果你真的想采用上述解决方案,请听从捷迪的建议;也就是说,生成一个匹配列表并对每个匹配执行替换。我会使用Regex表达式

@"@{.*?}" 

@"@{.*?ContractName.*?}"/@"@{.*?ContractorNumber.*?}"

但你想如何匹配它实际上取决于你和你需要什么。

编辑1:

在回顾了你最近的编辑并更好地了解了你在寻找什么之后,我设计了一个略显丑陋但功能强大的解决方案。任何有特权的人都可以自由清理,但我现在没有时间:

string yourstring = "{@</w:t></w:r><w:r><w:t>Obrigado</w:t></w:r><w:r><w:t>}{@......}...";
Regex reg1 = new Regex(@"{.*?@.*?}");
Regex reg2 = new Regex(@"<.*?>");
MatchCollection matches = reg1.Matches(yourstring);
List<string> names = new List<string>();
foreach (Match match in matches)
{
    // yeah.. this could be cleaned up. 
    names.Add((string)reg2.Replace(match.ToString(), ""));
}
for (int i = 0; i < names.Count; i++)
{
    yourstring = yourstring.Replace(matches[i].ToString(), names[i]);
}

我试着在一个前臂循环中完成所有这些,但比赛是只读的,除了第二次跑动之外,我现在想不出合理的方法来绕过它。我听说过递归Regex方法,但对它们了解不多。

有两种方法。如果每次要替换的字符串都是一样的,你可以只做

input.Replace("{@ContractNumber}","Actual Number");

如果他们可以随心所欲地称呼它,那么你可以这样做:

Regex reg = new Regex(@"{@['w|'d]+}");
string input = "test {@name} this out";
MatchCollection matches = reg.Matches(input);
foreach (Match m in matches)
{
    // Look up the value or whatever based on m.Value
    Console.WriteLine(m.Value);
}
Regex.Replace(sourceString, @"{@ContractName}", myContractName);
Regex.Replace(sourceString, @"{@ContractNumber}", myContractNumber);

确保在代码的顶部包含using System.Text.RegularExpressions;

您不能只"清除垃圾"而仍然拥有有效的XML。

以下是此解决方案的一些问题:

  • 是否将<w a="{@">作为字符串的一部分进行匹配
  • </w>介于两者之间而不是<w>时,你会怎么做
  • <w>介于两者之间而不是</w>时,你会怎么做

听起来你要么必须以某种方式清理你的输入,要么使用XML解析库和一些状态来艰难地完成这项工作。