Мне нужно объяснение, почему:
$test=`expr "hello" : "\([a-z]*\)"`; echo $test
выведет hello
, где как:
$test=`expr "hello" : "hel"`; echo $test
вернет количество совпадающих символов.
А также:
$ test=`expr "hello123there" : ".*o\([0-9]*\)"t`; echo $test
обратите внимание, что после этого .*
мне нужно указать, o
что нужно вернуть 123
, иначе ничего не вернётся.
решение1
Это прямо там, на странице руководства, например http://ss64.com/bash/expr.html
Соответствия шаблону возвращают строку, совпавшую между ( и ), или null; если ( и ) не используются, они возвращают количество совпавших символов или 0.
решение2
Вот какexpr
соответствующее выражениеработает.
Если шаблон содержит хотя бы одно подвыражение регулярного выражения , то будет возвращена [\(...\)]
строка, совпадающая с выражением обратной ссылки . matched , поэтому вы ее получили обратно.\1
hello
\([a-z]*\)
expr
использовалБРЭ, поэтому вам придется экранировать \(
и \)
для обозначения подвыражения. Использование (
и )
считается литеральным в BRE.
В противном случае вы получите количество совпавших символов.
В expr "hello123there" : ".*\([0-9]*\)"t
, вы получили пустую строку, возвращенную. Это потому, что жадность регулярного выражения,будет сопоставлена самая длинная подстрока.
Поскольку *
соответствует нулю или более символов, поэтому [0-9]*
может соответствовать нулю раз и .*
будет соответствовать самой длинной подстроке hello123
. Вот почему вы получили пустую строку.
Если у вас есть perl
, вы можете попробовать:
printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*([0-9]*)t/'
и:
printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*o([0-9]*)t/'
чтобы увидеть разницу.
Обратите внимание, что вы всегда должны заключать переменные в двойные кавычки. Если оставить переменные без кавычек, ваш скрипт можетзадохнулсяи приводя кдыры в безопасности.