`expr "hello" : "\([az]*\)"` 的含义?

`expr "hello" : "\([az]*\)"` 的含义?

我需要解释一下原因:

$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

它就在手册页中,EG http://ss64.com/bash/expr.html

模式匹配返回 ( 和 ) 之间匹配的字符串或 null;如果不使用 ( 和 ),则返回匹配的字符数或 0。

答案2

这就是如何expr匹配表达式作品。

如果模式至少包含一个正则表达式子表达式,则应返回[\(...\)]与反向引用表达式匹配的字符串。匹配,所以你把它找回来了。\1hello\([a-z]*\)

expr用过的布雷,所以你必须转义\(\)表示一个子表达式。在 BRE 中使用(and)被视为文字。

否则,您将获得匹配的字符数。


在 中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/'

看看差异。


请注意,您应该始终用双引号引用变量。将变量不加引号可以使您的脚本窒息并导致安全漏洞

相关内容