我正在尝试使用正则表达式匹配一些代码文件中注释内的TODO
等标记。例如,考虑以下文件:
foo bar # TODO
bar foo quux # TODO bar # TODO foo quux
quux # foo ## TODO foo # bar # TODO quux
'# TODO\'' # TODO
注意,一行中可能有多个标记,只要每个标记前面有#
,那么第二行和第三行应该匹配两次。此外,第一#
(实际代码)之前的前缀可以具有任意长度;这同样适用于每个TODO
后面的内容。除此之外,可能还有像# TODO
这样没有注释的子字符串(参见第四行;它应该匹配一次,最后的# TODO
)
我一直在Stackoverflow和其他网站上搜索,但似乎没有任何东西能够回答这样一个问题:在这些匹配之前有多个重叠的匹配项和一个可变长度的前缀。我认为问题主要在于试图结合上下文使用积极的lookaheads/lookbehinds:
(?=#\s*TODO[^#]*)
不起作用,因为它两次匹配第四行。这就是为什么我说重叠:似乎在匹配时必须考虑前缀的结构李>^[^#']*('[^'\\]*(\\.[^'\\]*)*'[^#']*)*(#\s*(?!TODO)[^#]*)*
匹配,这样我就可以正确地得到第四行,但这是一个可变长度的匹配,因此,就我所知,使用像(?<=^[^#']*('[^'\\]*(\\.[^'\\]*)*'[^#']*)*(#\s*(?!TODO)[^#]*)*)(#\s*TODO[^#]*)
这样的正向查找将导致每个正则表达式引擎上出现错误(如果工作,无论如何只会匹配第一个# TODO
)李>^[^#']*('[^'\\]*(\\.[^'\\]*)*'[^#']*)*(#\s*(?!TODO)[^#]*)*(?=(#\s*TODO[^#]*)(#\s*(?!TODO)[^#]*)*)
这样的正向前瞻也不起作用,因为它只匹配# TODO
的一个匹配项李>解释:\\.
匹配转义字符,[^'\\]*
任何不是转义字符和字符串分隔符的内容,因此'[^'\\]*(\\.[^'\\]*)*'
匹配任何字符串文字。在字符串文字部分之外使用[^#']*
意味着:匹配任何不以字符串或注释开头的内容,因此行的代码部分是^[^#']*('[^'\\]*(\\.[^'\\]*)*'[^#']*)*
。不包含标记的注释段可以通过#\s*(?!TODO)[^#]*
找到,因此整个前缀可以与^[^#']*('[^'\\]*(\\.[^'\\]*)*'[^#']*)*(#\s*(?!TODO)[^#]*)*
匹配
我使用ripgrep
,因此这适用于PCRE/PCRE2正则表达式。
然而,我对任何regex方言是否有解决方案感兴趣
我知道我可以匹配至少有一个正确匹配的行,并用一些脚本语言对结果进行后期处理,以从行中提取每个TODO
,但我想知道是否可以只执行此正则表达式
目前没有回答
相关问题 更多 >
编程相关推荐