首页 > 解决方案 > Notepad++ 正则表达式:如何防止 notepad++ 在搜索中嵌入不需要的字符?

问题描述

我最近在 notepad++ 中发布了一个关于正则表达式的问题,因为我不够强大,无法理解正则表达式的所有微妙之处。

在一个 xml 文件中,我需要插入这个标签:

<?Pub Dtl?>

下面是一个字符串的例子:

<pgblk chapnbr="53" sectnbr="51" subjnbr="22" pgblknbr="0" chg="u" key="pgblk-53-51-22-0-1" revdate="20200225"><title>

或者

<pgblk chapnbr="53" sectnbr="51" subjnbr="22" pgblknbr="0" chg="u" key="pgblk-53-51-22-0-1" revdate="20200225"><isempty>

这是我第一个有效的搜索模式:

<pgblk chapnbr(.+?)>(<title>|<isempty\/>)

和替换模式:

<pgblk chapnbr\1><?Pub Dtl?>\2

但是,如果标签已经存在,它会被包含在搜索中:我写的搜索模式发现:

<pgblk chapnbr="53" sectnbr="51" subjnbr="22" pgblknbr="0" chg="u" key="pgblk-53-51-22-0-1" revdate="20200225"><?Pub Dtl?><title>

<?Pub Dtl?>找到了,但我不希望这样,否则如果我使用替换模式,我会得到 <?Pub Dtl?>两次!

我试过:

<pgblk chapnbr(.+?)[>?](<title>|<isempty\/>)

但结果是一样的。添加[>?]的事实并没有改变任何东西。我很好理解?是惰性字符,但为什么搜索模式包含<?Pub Dtl?>并且不会停止到第一个结束标记?令人难以置信的是,它嵌入了<?Pub Dtl?>的第二个结束标签,而不是第一个或第三个标签,例如:<title>。这很复杂......我用 regex101.com 进行了培训,但没有管理。如果有人可以在我无知的浩瀚海洋上投下一些光…… 多多益善。

标签: regexnotepad++

解决方案


您可以在两者之间进行匹配,除了<?Pub Dtl?>使用重复组断言您不想匹配的右侧字符串之外(?:(?!<\?Pub Dtl\?>).)*)

请注意,在示例数据中,有<isempty>和没有<isempty/>

如果你想同时匹配两者,你可以/选择 using<isempty/?>并且你不必转义正斜杠。

<pgblk chapnbr((?:(?!<\?Pub Dtl\?>).)*)>(<title>|<isempty>)

模式匹配:

  • <pgblk chapnbr从字面上匹配
  • (捕获组 1
    • (?:非捕获组
      • (?!<\?Pub Dtl\?>).<?Pub Dtl?>负前瞻,不直接向右断言。如果该断言为真,则匹配除换行符以外的任何字符,使用.
    • )*关闭非捕获组并选择性地重复它
  • )关闭组 1
  • >从字面上匹配
  • (捕获组 2
    • <title>|<isempty>匹配其中一个选项
  • )关闭组 2

用。。。来代替

<pgblk chapnbr\1><?Pub Dtl?>\2

正则表达式演示


推荐阅读