找到&替换xml文档中父项中子项的重新匹配匹配项

时间:2018-02-09 14:50:34

标签: regex xml replace find notepad++

我用的是什么: Windows 7和记事本++

我有什么:

<title name="titleA1\titleA2\titleA3">
    <description>descriptionA1</description>
    <info name="infoA1.ext" size="numberA1"/>
    <info name="infoA2.ext" size="numberA2"/>
</title>
<title name="titleB1\titleB2">
    <description>descriptionB1</description>
    <info name="infoB1.ext" size="numberB1"/>
</title>
<title name="titleC1\titleC2\titleC3\titleC4">
    <description>descriptionC1</description>
    <info name="infoC1.ext" size="numberC1"/>
    <info name="infoC2.ext" size="numberC2"/>
    <info name="infoC3.ext" size="numberC3"/>
</title>

我想要的: 我需要在父级内的最后一个反斜杠之后的文本 - &#34;标题名称&#34;,添加到他们的孩子 - &#34;信息名称&#34; (在他们的名字的开头)。 我还需要标题名称,以便在第一个反斜杠后删除所有内容 像这样:

<title name="titleA1">
    <description>descriptionA1</description>
    <info name="titleA3\infoA1.doc" size="numberA1"/>
    <info name="titleA3\infoA2.doc" size="numberA2"/>
</title>
<title name="titleB1">
    <description>descriptionB1</description>
    <info name="titleB2\infoB1.doc" size="numberB1"/>
</title>
<title name="titleC1">
    <description>descriptionC1</description>
    <info name="titleC4\infoC1.doc" size="numberC1"/>
    <info name="titleC4\infoC2.doc" size="numberC2"/>
    <info name="titleC4\infoC3.doc" size="numberC3"/>
</title>

我尝试的是:

查找

\t<title name="(.*?)\\(.*?)">(.*?)<description>(.*?)</description>(.*?)info name="(.*?)"(.*?)</title>

替换为

\t<title name="$1">$3<description>$4</description>$5info name="$2\\$6"$7</title>

我的问题:

  1. 它不会寻找&#34; last&#34;标题名称文字中的反斜杠。
  2. 仅替换第一个子信息名称,而不是所有子项。
  3. 我不知道如何修改正则表达式以删除标题名称,只保留第一个反斜杠之前的第一个文本段落。
  4. 我的问题是:

    • 如何只抓取标题名称中最后一个反斜杠后面的文字?
    • 如何将抓取的文本添加到标题名称的子信息名称?
    • 如何在名称中第一个反斜杠之前将标题名缩短为文本?

    我的谢意: 对任何可以帮助我的人

1 个答案:

答案 0 :(得分:0)

我做了多次尝试,但结束了以下方式。一些脚本或编码肯定会更好。

  1. 标题名称中的最后反斜杠
  2. 正如已经说过的那样,依靠不情愿的量词你所采用的方式并不允许仅捕获名称属性中最终\之后的部分。
    我会使用一些对比来继续进行,例如<title name="(?:[^\\"]+\\)*([^\\"]+)">分解为:

    <title name="
      (?:          # Non-capturing group
        [^\\"]+    # Matches any character but a \ or a ", as much as you can
        \\         # Followed by a \
      )*           # Repeat as much as you can (that way, all 
      ([^\\"]+)    # Capture next non \ or " characters in group 1
    ">
    
    1. 替换所有子信息名称
    2. 在这里,我不认为每个孩子可以多次更换/插入,因为:

      • 符合条件的多次替换,只需依靠输入即可生效。
      • Boost引擎(由Notepad ++使用)不允许可变长度的后视。
      • 即使可变长度前瞻使得重叠匹配成为可能,它也不会允许替换,因为它们是零长度匹配(不移动,即使你捕获任何东西也是空匹配;然后只剩下可能性了当前位置)。

      我们仍然可以继续进行连续替换。

      我将继续使用以下正则表达式:<title name="(?:[^\\"]+\\)*([^\\"]+)">(?:(?!<title).)*?<info name="(?!\1\\)\K,它将分解为:

      <title name="(?:[^\\"]+\\)*([^\\"]+)">  # Seen at point 1
      (?:(?!<title).)*?                       # Do not capture but consume every character not followed by <title (ensures not leaking to next title tag), bactrack if needed
      <info name="(?!\1\\)                    # Match info tag having a name which do not start by group 1 content (allows successive replacements without duplication)
      \K                                      # Stop here and discard match (but not group 1 content)
      

      然后,我们可以继续插入我们的第1组令牌:$1\\ 重复直到没有替换为止。

      1. 仅保留标题名称中的第一个标记
      2. 遵循相同的对比度规则并匹配重置,使用<title name="[^\\"]+\K[^"]*并替换为空:匹配将在标题名称中的第一个\之后重置,有效地匹配从该位置到下一个&#34;的所有字符。