I need a explanation of why:

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

would print out hello, where as:

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

would return the number of characters matching.

And also:

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

notice after .* I have to specify the o for it to return 123, otherwise it would not return anything.


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


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.


It's right there in the man page, E.G. http://ss64.com/bash/expr.html

Pattern matches return the string matched between ( and ) or null; if ( and ) are not used, they return the number of characters matched or 0.

  • @Yangfan: You mean why \( and \) were used instead of ( and ) as above link said? – cuonglm Feb 15 '16 at 3:53
  • @cuonglm I was looking for an answer as to why substring pattern is only matched if characters before and after the pattern are specified? if this confuses you I can update my question with an example – 夢のの夢 Feb 15 '16 at 3:55
  • @Yangfan: I updated my answer with more details. Please remove chatty comments. Thanks. – cuonglm Feb 15 '16 at 4:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.