Significado de `expr "olá": "\([az]*\)"`?

Significado de `expr "olá": "\([az]*\)"`?

Preciso de uma explicação do porquê:

$test=`expr "hello" : "\([a-z]*\)"`; echo $test

imprimiria hello, onde como:

$test=`expr "hello" : "hel"`; echo $test

retornaria o número de caracteres correspondentes.

E também:

$ test=`expr "hello123there" : ".*o\([0-9]*\)"t`; echo $test

aviso depois que .*eu tenho que especificar opara ele retornar 123, caso contrário não retornaria nada.

Responder1

Está ali na página de manual, EG http://ss64.com/bash/expr.html

As correspondências de padrões retornam a string correspondente entre ( e ) ou nulo; se ( e ) não forem usados, eles retornam o número de caracteres correspondentes ou 0.

Responder2

É assim queexprexpressão correspondentefunciona.

Se o padrão contiver pelo menos uma subexpressão de expressão regular [\(...\)], a string correspondente à expressão de referência anterior \1deverá ser retornada. hellocorrespondido \([a-z]*\), então você o recuperou.

exprusadoBRE, então você precisa escapar \(e \)denotar uma subexpressão. Usar (e )é considerado literal no BRE.

Caso contrário, você obteve o número de caracteres correspondentes.


Em expr "hello123there" : ".*\([0-9]*\)"t, você recebeu uma string vazia retornada. Isso porque a ganância da expressão regular,a substring mais longa será correspondida.

Como *corresponde a zero ou mais caracteres, [0-9]*pode corresponder a zero vezes e .*corresponderá à substring mais longa hello123. É por isso que você obteve a string vazia.

Se você tiver perl, você pode tentar:

printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*([0-9]*)t/'

e:

printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*o([0-9]*)t/'

para ver a diferença.


Observe que você deve sempre colocar aspas duplas em suas variáveis. Deixar variáveis ​​sem aspas pode tornar seu scriptsufocadoe levando afalhas de segurança.

informação relacionada