使用负面lookbehind的正则表达式在Notepad ++中不起作用

时间:2013-06-24 23:17:13

标签: regex notepad++ regex-lookarounds negative-lookbehind

我有一个源文件,其中包含数百个字符串flecha.jpgflecha1.jpg,但我需要找到任何其他.jpg图像的出现位置(即casa.jpgmoto.jpg,无论如何)

我尝试使用带有负向lookbehind的正则表达式,如下所示:

(?<!flecha|flecha1).jpg

但它不起作用! Notepad ++只是说它是一个无效的正则表达式。

我在其他地方试过了正则表达式并且它有效,here is an example所以我猜这是NPP处理正则表达式或者使用lookbehinds / lookaheads语法的问题。

那么我怎么能在NPP中获得相同的正则表达式结果呢?

如果有用,我使用的是Notepad ++ 6.3版Unicode

作为一个额外的,如果你很善良,那么实现同样的东西的语法是什么,但是可选的数字(在这种情况下只有'1')作为我的字符串的后缀? (即使它在NPP中不起作用,只是为了知道)......

我尝试了(?<!flecha[1]?).jpg,但它不起作用。它应该与其他正则表达式相同,请参见此处(RegExr

3 个答案:

答案 0 :(得分:16)

Notepad ++似乎没有实现可变长度的后视(这在一些工具中会发生)。解决方法是使用多个固定长度的后视:

(?<!flecha)(?<!flecha1)\.jpg

您可以查看the matches are the same。但这适用于npp。

请注意,我转发了.,因为您要尝试匹配扩展程序,您想要的是文字.。你的方式,它是一个通配符 - 可能是任何角色。

关于额外的问题,不幸的是,由于我们不能拥有可变长度的后视镜,因此不可能有可选的后缀(数字),而不需要多个后视镜。

答案 1 :(得分:4)

解决Notepad ++

中可变长度负向外观限制的问题

这里给出了几种在Notepad ++(或任何具有相同限制的正则表达式引擎)中解决此限制的策略

定义问题

Notepad ++不支持使用可变长度负向lookbehind断言,并且有一些解决方法会很好。让我们考虑原始问题中的示例,但假设我们希望避免在flecha之后使用任何位数的flecha文件的出现,以及任何flecha之前的字符。在这种情况下,使用可变长度负向外观的正则表达式看起来像(?<!flecha[0-9]*)\.jpg

我们的字符串想要在此示例中匹配

  • flecha.jpg
  • flecha1.jpg
  • flecha00501275696.jpg
  • aflecha.jpg
  • img_flecha9.jpg
  • abcflecha556677.jpg

策略

  1. 插入临时标记

    首先对要避免使用的实例执行查找和替换 - 在我们的示例中为flecha[0-9]*\.jpg的实例。插入一个特殊标记,以形成一个不会出现在其他任何地方的图案。对于此示例,我们将在.之前插入额外的.jpg,假设..jpg没有出现在其他位置。所以我们这样做:

    查找:(flecha[0-9]*)(\.jpg)

    替换为:$1.$2

    现在,您可以使用简单的正则结构.jpg\w+\.jpg在文档中搜索所有其他(?<!\.)\.jpg个文件名,并使用它们执行您想要的操作。完成后,执行最终的查找和替换操作,将..jpg的所有实例替换为.jpg,以删除临时标记。

  2. 使用否定先行断言

    可以使用负前瞻断言来确保您不匹配不需要的文件名:

    (?<!\S)(?!\S*flecha\d*\.jpg)\S+\.jpg

    打破它:

    • (?<!\S)通过断言您的匹配前面没有非空白字符,确保您的匹配从文件名的开头开始,而不是在中间。
    • (?!\S*flecha\d*\.jpg)确保匹配的内容不包含我们想要避免的模式
    • \S+\.jpg实际上是匹配的 - 一串非空白字符后跟.jpg
  3. 使用多个固定长度的负面观察

    对于您不想匹配的模式具有少量可能长度的情况,这是一种快速(但不那么优雅)的解决方案。

    例如,如果我们知道flecha后面最多只有三位数,那么我们的正则表达式可能是:

    (?<!flecha)(?<!flecha[0-9])(?<!flecha[0-9][0-9])(?<!flecha[0-9][0-9][0-9])\.jpg

答案 2 :(得分:2)

您是否知道您只是在(消费)意义上匹配扩展程序(.jpg)?我想你想匹配整个文件名,不是吗?使用前瞻更容易做到:

\b(?!flecha1?\b)\w+\.jpg

第一个\b将匹配锚定到名称的开头(假设它实际上是我们正在查看的文件名)。然后(?!flecha1?\b)断言该名称不是flechaflecha1。完成后,\w+继续并消耗名称。然后\.jpg抓住扩展程序以完成比赛。