多个字符串的负向前瞻

多个字符串的负向前瞻

我需要找到的用法短开标签在 PHP 文件中,这意味着匹配<?但不匹配<?php, <?xml, 或<?=.在大多数正则表达式风格中,会是这样的:

 <\?(?!php|xml|=)

但是,以下行匹配不需要的<?php<?xml<?=部分:

$ grep -r -E "<\?(?\!php|=|xml)" *

我尝试了多种反斜杠-P-e标志的排列。如何在 GNU grep 中正确使用否定前瞻?

CentOS 7.3(KDE 桌面),GNU grep 2.20(在线文档适用于3.0,但我man本地有),雀巢无咖啡因咖啡(这实际上可能是真实的问题)。

答案1

您需要-PPCRE 来实现 Perl(?!...)负向前瞻,并且不是逃脱!(?!...)

-bash-4.2$ cat input
<?php
<?xml
<?=
<?okay
<?
-bash-4.2$ grep -P '<\?(?!php|xml|=)' input
<?okay
<?
-bash-4.2$ 

"<\?(?\!php|=|xml)"是不正确的,因为它传递(?\!...)给正则表达式引擎grep,并且?\!完全不?!涉及正则表达式引擎;如果您不确定 shell 正在将什么传递给程序,请编写一些代码来检查:

$ perl -E 'printf "%*vd\n","\t",$ARGV[0];say join "\t",split //,$ARGV[0]' "?\!"
63  92  33
?   \   !
$ 

或者使用类似的东西strace来看看得到grep了什么:

-bash-4.2$ strace -o grep grep "?\!grep" /etc/passwd
-bash-4.2$ grep grep grep
execve("/usr/bin/grep", ["grep", "?\\!grep", "/etc/passwd"], [/* 24 vars */]) = 0
-bash-4.2$ 

相关内容