正则表达式否定性落后于后方忽略评论命中

时间:2019-08-28 03:37:18

标签: regex-lookarounds

我想为grep编写一个RegEx,以查找包含特定字符串的源文件,只要它没有被注释掉即可。也就是说,只要没有在同一行中的注释符号之前,它就应该找到目标字符串。

使用负向后视,我已经能够接近所需的结果,但是还不能完全解决问题。

示例源代码是Basic,但是同样的难题也适用于其他语言。

示例语句:

  0010 OPEN (7)"T999"
  0020 IF A$="D" THEN OPEN (7)"T999"

但是忽略:

  0030 REM OPEN (7)"T999"
  0040 REM IF A$="D" THEN OPEN (7)"T999"

此RegEx仅查找感兴趣的主要字符串。

  OPEN \(.+\)\"T999\"

此正则表达式

  (?<!REM) OPEN \(.+\)\"T999\"

查找第0010和0020行,拒绝第0030行,但包括第0040行。

这是因为后向搜索仅查看紧接主搜索词之前的位置(减去一个空格)。

我试图扩展这种想法:

  (?<!REM).+OPEN \(.+\)\"T999\"

...但是这导致了回溯部分无效,并且接受了主搜索的所有实例,无论是否进行了REM。

因此,关键问题似乎是如何使后视看起来像在主搜索词(同一行)之前的可变距离。

想法?

我正在使用的grep实际上是FileLocator Pro,其搜索语法设置为与Perl兼容。据说遵循以下语法: https://www.boost.org/doc/libs/1_36_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html

1 个答案:

答案 0 :(得分:1)

由于您只想查找行而不是特定文本,因此应从文件开头开始匹配。

如果您确实想要文本,请使用捕获组。

类似这样的东西:

(?m)^\d+\s+(?!REM).*(OPEN \(.+\)\"T999\")

请参阅regex101.com上的DEMO