Ich brauche eine Erklärung, warum:
$test=`expr "hello" : "\([a-z]*\)"`; echo $test
würde ausgedruckt hello
, wobei:
$test=`expr "hello" : "hel"`; echo $test
würde die Anzahl der übereinstimmenden Zeichen zurückgeben.
Und auch:
$ test=`expr "hello123there" : ".*o\([0-9]*\)"t`; echo $test
Beachten Sie, dass .*
ich angeben muss , o
was zurückgegeben werden soll 123
, sonst würde es nichts zurückgeben.
Antwort1
Es steht direkt auf der Manpage, EG http://ss64.com/bash/expr.html
Musterübereinstimmungen geben die zwischen ( und ) übereinstimmende Zeichenfolge oder null zurück; wenn ( und ) nicht verwendet werden, geben sie die Anzahl der übereinstimmenden Zeichen oder 0 zurück.
Antwort2
So geht dasexpr
passender Ausdruckfunktioniert.
Wenn das Muster mindestens einen Teilausdruck eines regulären Ausdrucks enthält [\(...\)]
, soll die mit dem Rückreferenzausdruck übereinstimmende Zeichenfolge \1
zurückgegeben werden. Sie hello
haben \([a-z]*\)
sie also zurückbekommen.
expr
gebrauchtBRE, daher müssen Sie \(
und maskieren, \)
um einen Unterausdruck zu kennzeichnen. Die Verwendung von (
und )
wird in BRE als wörtlich betrachtet.
Andernfalls erhalten Sie die Anzahl der übereinstimmenden Zeichen.
In expr "hello123there" : ".*\([0-9]*\)"t
wurde ein leerer String zurückgegeben. Das liegt an der Gier des regulären Ausdrucks,der längste Teilstring wird abgeglichen.
Da *
null oder mehr Zeichen übereinstimmen, [0-9]*
kann es null Mal übereinstimmen und es .*
wird mit der längsten Teilzeichenfolge übereinstimmen hello123
. Deshalb haben Sie die leere Zeichenfolge erhalten.
Wenn ja perl
, können Sie Folgendes versuchen:
printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*([0-9]*)t/'
Und:
printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*o([0-9]*)t/'
um den Unterschied zu sehen.
Beachten Sie, dass Sie Ihre Variablen immer in Anführungszeichen setzen sollten. Wenn Sie Variablen nicht in Anführungszeichen setzen, kann Ihr Skriptersticktund führt zuSicherheitslücken.