我需要找到的用法短开标签在 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
您需要-P
PCRE 来实现 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$