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.
\([a-z]*\), so you got it back.
expr used BRE, so you have to escape
\) to denote a subexpression. Using
) is considered literal in BRE.
Otherwise, you got the number of characters matched.
expr "hello123there" : ".*\([0-9]*\)"t, you got empty string returned. That's because the greediness of regular expression, the longest substring will be matched.
* 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/'
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.