正则表达式只替换给定xml节点中的子字符串

时间:2013-06-21 13:14:45

标签: c# xml regex xliff

如果在< target> XML节点中找到给定的子字符串“/ oem / en”(后跟正斜杠或双引号“),我试图写一个只返回匹配的正则表达式是徒劳的单行XLIFF代码。到目前为止,我得到了它,但它仍然匹配< source>节点中的偶然事件:

/oem/en(?=/|\")(?=.*?</target>)

&lt; source&gt;的XLIFF代码示例和&lt; target&gt;节点:

<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file product-version="1.4" original="" source-language="default" target-language="default" datatype="plaintext" category="page_content"><header></header><body><trans-unit id="page_description" datatype="x-System.String" maxwidth="0" minwidth="0"><source><![CDATA[bla bla]]></source><target><![CDATA[translated bla bla]]></target></trans-unit><trans-unit id="f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8" datatype="x-System.String" resname="PublishingPageContent" maxwidth="0" minwidth="0"><source><![CDATA[<a href="/oem/en/link1">bla bla</a>]]></source><target><![CDATA[<a href="/oem/en/link1/>translated bla bla</a>]]></target></trans-unit><trans-unit id="f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8" datatype="x-System.String" resname="PublishingPageContent" maxwidth="0" minwidth="0"><source><![CDATA[<a href="/oem/en/link2">bla bla</a>]]></source><target><![CDATA[<a href="/oem/en/link2/>translated bla bla</a>]]></target></trans-unit></body></file></xliff>

我的方法是尝试制作一个向前看的表达式,直到它匹配&lt; / source&gt;或&lt; / target&gt;如果它首先找到前者,则意味着我们在&lt; source&gt;节点,因此它不匹配。

非常感谢您对此的帮助!

2 个答案:

答案 0 :(得分:3)

描述

如果表达式位于目标标记

中,则此表达式将仅找到/oem/en字符串

正则表达式:(<target>(?:(?!<\/target>).)*?)(\/oem\/en(?=\/|\"))

替换为:$1~~~~New Value~~~~~

enter image description here

C#代码示例

输入文字

<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file product-version="1.4" original="" source-language="default" target-language="default" datatype="plaintext" category="page_content"><header></header><body><trans-unit id="page_description" datatype="x-System.String" maxwidth="0" minwidth="0"><source><![CDATA[bla bla]]></source><target><![CDATA[translated bla bla]]></target></trans-unit><trans-unit id="f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8" datatype="x-System.String" resname="PublishingPageContent" maxwidth="0" minwidth="0"><source><![CDATA[<a href="/oem/en/link1">bla bla</a>]]></source><target><![CDATA[<a href="/oem/en/link1/>translated bla bla</a>]]></target></trans-unit><trans-unit id="f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8" datatype="x-System.String" resname="PublishingPageContent" maxwidth="0" minwidth="0"><source><![CDATA[<a href="/oem/en/link2">bla bla</a>]]></source><target><![CDATA[<a href="/oem/en/link2/>translated bla bla</a>]]></target></trans-unit></body></file></xliff>

<强>代码

using System;
using System.Text.RegularExpressions;
namespace myapp
{
  class Class1
    {
      static void Main(string[] args)
        {
          String sourcestring = "source string to match with pattern";
          String matchpattern = @"(<target>(?:(?!<\/target>).)*?)(\/oem\/en(?=\/|\""))";
          String replacementpattern = @"$1~~~~~new value~~~~~";
          Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern,RegexOptions.IgnoreCase));
        }
    }
}

<强>产量

<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file product-version="1.4" original="" source-language="default" target-language="default" datatype="plaintext" category="page_content"><header></header><body><trans-unit id="page_description" datatype="x-System.String" maxwidth="0" minwidth="0"><source><![CDATA[bla bla]]></source><target><![CDATA[translated bla bla]]></target></trans-unit><trans-unit id="f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8" datatype="x-System.String" resname="PublishingPageContent" maxwidth="0" minwidth="0"><source><![CDATA[<a href="/oem/en/link1">bla bla</a>]]></source><target><![CDATA[<a href="~~~~~new value~~~~~/link1/>translated bla bla</a>]]></target></trans-unit><trans-unit id="f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8" datatype="x-System.String" resname="PublishingPageContent" maxwidth="0" minwidth="0"><source><![CDATA[<a href="/oem/en/link2">bla bla</a>]]></source><target><![CDATA[<a href="~~~~~new value~~~~~/link2/>translated bla bla</a>]]></target></trans-unit></body></file></xliff>

答案 1 :(得分:1)

我不认为这是可靠的而不需要CDATA部分。

以下是正则表达式。它找到目标标签后跟CDATA。然后匹配任何未跟随CDATA关闭的字符]]。只要遇到[],就不会匹配 / oem / en 。我相信C#支持否定的前瞻和非捕获组。显然否定了展望是至关重要的。

<target><!\[CDATA\[(?:.(?!\]\]))*(/oem/en)

如果您需要容纳具有参数的目标,您可以执行<target[^>]*>之类的操作。如果目标和CDATA之间会有空格,那么`\ w *

我有一个非常alpha的正则表达式编辑器,但你可以测试它:http://rey.gimenez.biz/