Lookahead negativo em várias strings

4

Eu preciso encontrar usos de Tags abreviadas em PHP arquivos, o que significa corresponder <? , mas não <?php , <?xml ou <?= . Na maioria dos sabores de regex, isso seria algo assim:

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

No entanto, a linha a seguir corresponde às porções indesejadas <?php , <?xml e <?= :

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

Eu testei várias permutações de barras invertidas, -P e -e flags. Como alguém usa corretamente um lookahead negativo no grep do GNU?

CentOS 7.3 (área de trabalho do KDE), GNU grep 2.20 (os documentos on-line são para 3.0, mas eu tenho man localmente), Nescafé Decaff (isso pode realmente ser o problema real ).

    
por dotancohen 17.07.2017 / 19:09

1 resposta

7

Você precisará de -P para a PCRE, que implementa a antecipação% Perl (?!...) negativa e para não escapar da ! na (?!...) .

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

"<\?(?\!php|=|xml)" está incorreto, pois isso passa (?\!...) para grep e ?\! não é totalmente ?! no que diz respeito ao mecanismo de expressões regulares; se você não tiver certeza do que está sendo passado para um programa pelo shell, escreva algum código para inspecionar isso:

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

Ou use algo como strace para ver o que o grep obteve:

-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$ 
    
por 17.07.2017 / 19:24