查找并替换xml文档中父项中子项的重新匹配匹配项

问题描述 投票:-2回答:1

我使用的是: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>

我想要的是:我需要在父级中的最后一个反斜杠之后的文本 - “标题名称”,添加到他们的孩子 - “信息名称”(在他们的名字的开头)。我还需要标题名称,以便在第一个反斜杠后删除所有内容,如下所示:

<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. 它不会在标题名称文本中查找“最后”反斜杠。
  2. 仅替换第一个子信息名称,而不是所有子项。
  3. 我不知道如何修改正则表达式以剥离标题名称只保留第一个反斜杠之前的第一个文本段落。

我的问题是:

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

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

regex xml replace find notepad++
1个回答
0
投票

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

  1. 标题名称中的最后一个反斜杠

正如已经说过的那样,依靠不情愿的量词你所采用的方式不允许仅捕获名称属性中最终\之后的部分。 我会使用一些对比来继续,像<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. 替换所有子信息名称

在这里,我不认为每个孩子可以多次更换/插入,因为:

  • 符合条件的多次替换在一次仅依赖于输入的情况下是有效的。
  • 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. 仅保留标题名称中的第一个标记

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

© www.soinside.com 2019 - 2024. All rights reserved.