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 o
para 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 queexpr
expressã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 \1
deverá ser retornada. hello
correspondido \([a-z]*\)
, então você o recuperou.
expr
usadoBRE, 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.