Значение `expr 'hello": "\ ( * \)" `?

Мне нужно объяснение, почему:

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

распечатал бы hello , где:

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

будет возвращать количество совпадающих символов.

А также:

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

уведомление после .* Я должен указать o для его возврата 123 , иначе он ничего не вернет.

Вот как работает выражение соответствия expr .

Если шаблон содержит по крайней мере одно подвыражение регулярного выражения [\(...\)] , возвращается строка, соответствующая обратному ссылочному выражению \1 . hello соответствует \([az]*\) , так что вы вернули его.

expr используется BRE , поэтому вам нужно убежать \( и \) чтобы обозначить подвыражение. Использование ( и ) считается литералом в 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/' 

чтобы увидеть разницу.


Обратите внимание, что вы всегда должны удвоить кавычки своих переменных. Оставляя переменные без кавычек, вы можете заставить ваш сценарий задохнуться и привести к дырам в безопасности .

Это прямо на странице руководства, EG http://ss64.com/bash/expr.html

Образцы шаблонов возвращают строку, совпадающую между (и) или нулевым; Если (и) не используются, они возвращают количество совпадающих символов или 0.