我需要解释一下原因:
$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
匹配表达式作品。
如果模式至少包含一个正则表达式子表达式,则应返回[\(...\)]
与反向引用表达式匹配的字符串。匹配,所以你把它找回来了。\1
hello
\([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/'
看看差异。