That's how expr
matching expression works.
If the pattern contains at least one regular expression subexpression [\(...\)]
, the string matched by the back-reference expression \1
shall be returned. hello
matched \([a-z]*\)
, so you got it back.
expr
used BRE, so you have to escape \(
and \)
to denote a subexpression. Using (
and )
is considered literal in BRE.
Otherwise, you got the number of characters matched.
In expr "hello123there" : ".*\([0-9]*\)"t
, you got empty string returned. That's because the greediness of regular expression, the longest substring will be matched.
Because *
match zero or more characters, so [0-9]*
can match zero times, and .*
will match the longest substring hello123
. That's why you got the empty string.
If you have perl
, you can try:
printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*([0-9]*)t/'
and:
printf "hello123there" | perl -Mre=debugcolor -ne 'print $1 if /.*o([0-9]*)t/'
to see the difference.
Note that you should always double quotes your variables. Leaving variables un-quote can make your script choked and leading to security holes.