I want to match one or more occurance for ex. of blah using expr.
This works.
$ expr "blahblahblah" : 'blahblah'
8
What is wrong with this regular expression?
$ expr "blahblahblah" : '\(blah\)\+'
blah
I want the number of characters matched.
I want to match one or more occurance for ex. of blah using expr.
This works.
$ expr "blahblahblah" : 'blahblah'
8
What is wrong with this regular expression?
$ expr "blahblahblah" : '\(blah\)\+'
blah
I want the number of characters matched.
Since your question is tagged bash, there are better facilities than expr in modern versions of the shell, which do exactly what you want:
$ re='(blah)+'
$ [[ foo_blahblah_bar =~ $re ]] && echo "${#BASH_REMATCH[0]}"
8
First of all, you need \(\) instead of () and \+ instead of +.
But that is not all.
You can't use groups () and get the length of matched string simultaneously.
Pattern matches return the string matched between ( and ) or null; if ( and ) are not used, they return the number of characters matched or 0.
You must use wc to get the length of the string:
$ expr "blahblahblahblah" : '\(\(blah\)\+\)' | wc -c
17
Or using parameters expansion:
$ m=$(expr "blahblahblahblah" : '\(\(blah\)\+\)')
$ echo ${#m}
16
(wc -c counts the end of line also, hence the difference).
But if you can write the regular expression without groups, you get the length:
$ expr "blahhhhhbl" : "blah\+"
8
type expr; turns out it's an external command, so there's fork+wait+read overhead in running it no matter what.wc -c. And your answer ([[ =~ ]]) is even better