基本上我想在未注释的行上找到 foobar,例如:
// foobar # do not match me
foobar # match me
otherfoobar # do not match me
为了匹配注释行,我使用这个:^(\s*//\s*)\bfoobar\b.*$
如何匹配未注释的行?
笔记:
为了避免不必要的努力,请将答案限制为“^...$”。这必须纯粹在发送到 perl 进行匹配的字符串内完成。
另外 foobar 必须整体匹配,如 \bfoobar\b
最后, \bfoobar\b 前面不应该有任何东西,除了空格或注释签名。
答案1
foobar
a 右侧未找到的 a可以//
表示为:
^(?:(?!//).)*\bfoobar\b
*
这是一个由 0 个或多个 ( ) 个字符 ( )组成的序列,每个字符都不位于序列 ( ).
的开头,后跟由单词边界分隔的字符。//
(?!//)
foobar
答案2
如果您使用的是 Perl(语言),而不是使用与 Perl 兼容的正则表达式的工具,则没有理由将自己限制为仅使用一个正则表达式。
像这样的东西只会匹配未注释的行:
$ perl -ne 'print if not m,^\s*//, and /\bfoobar\b/' < file.txt
foobar # match me
即使使用其他实用程序或非 Perl 正则表达式,仅使用多个正则表达式可能是最简单的:
$ < file.txt grep -ve '//' | grep '\<foobar\>'
foobar # match me
相反,如果您仅限于单个 Perl 正则表达式,那么这应该可以工作:
grep -P '^\s*+(?!//).*\bfoobar\b.*$' file.txt
这\s*+
是一个“占有欲”表达,它匹配所有前导空格,并且不放开他们。然后(?!//)
检查前导空格后面的内容是否不是注释标记,最后我们foobar
在该行的任何位置查找断字内。
(如果在没有所有格限定符的情况下匹配空白,则正则表达式引擎可能会从前导空白中退出,并检查错误位置的注释标记,从而导致注释行被匹配。)
测试数据:
$ cat file.txt
// foobar # do not match
foobar # 1st match
otherfoobar # do not match
something foobar # 2nd and final match
$ grep -P '^\s*+(?!//).*\bfoobar\b.*$' file.txt
foobar # 1st match
something foobar # 2nd and final match
答案3
我认为否定的问题不应该过于复杂。
例如说我想拒绝这些行:
"^(\s*//\s*).*(\bfoobar\b).*$"
IE。'//'
在开头的空白处有注释签名,后跟包含'foobar'
整个单词的任何内容(为了清楚起见,包含括号)。
为了否定这一点,我们这样做:
"^(?!\s*//\s*).*(\bfoobar\b).*$"
我们只是替换(\s*//\s*)
为(?!\s*//\s*)
'//'
这会忽略开头处的空白处具有注释签名的任何内容,后跟我们的模式。
结果:
// foobar will not be matched
// whatever foobar will not be matched
foobar will be matched
whatever foobar will be matched
whateverfoobar will not be matched
笔记:.*
您可以通过更改之前的(\bfoobar...
设置来进一步微调。
例如我可以做"^(?!\s*//\s*)\s*(\bfoobar\b).*$"
foobar will be matched
whatever foobar will **NOT** be matched
警告:'foobar'
如果你用一些任意的字符串 替换,比如'${foobar}'
你尝试上面的方法,它将会失败。原因是因为您正常的“foobar”仅由单词字符组成,现在(\bfoobar\b)
将不匹配它。在这种情况下,\b
必须去除。