Hello,
On 10/26/2016 12:15 PM, Paul Eggert wrote:
There's no bug here: "expr E" exits with status 1 if E evaluates to 0, and expressions
like "0 : '\([0-9]\)$'" do evaluate to 0.
Worth mentioning that this is a known "gotcha", explained here:
http://www.pixelbeat.org/docs/coreutils-gotchas.html#expr
And to elaborate as to why, consider the same regex without grouping - 'expr'
will return the *number of characters matched*,
so:
$ expr 0 : '[0-9]$'
1
$ expr 1 : '[0-9]$'
1
$ expr 4 : '[0-9]$'
4
$ expr 9 : '[0-9]$'
1
$ expr a : '[0-9]$'
0
Because you've added grouping, 'expr' returns the *actual matched characters*:
$ expr 0 : '\([0-9]\)$'
0
$ expr 1 : '\([0-9]\)$'
1
$ expr 4 : '\([0-9]\)$'
4
$ expr 9 : '\([0-9]\)$'
9
$ expr a : '\([0-9]\)$'
[[ empty string ]]
And the "gotcha" is that 'expr' uses the resulting value as exit code. If the value is
the string "0" or the value 0 or an empty string - the exit code will be 1 (failure). In
your example, the exit code should not be used to distinguish between matched '0' and non-matching
string:
$ expr 0 : '\([0-9]\)$' ; echo $?
0
1
$ expr a : '\([0-9]\)$' ; echo $?
1
Instead, if you use grouping, save the result into a variable and check if it's
empty:
$ A=$(expr 0 : '\([0-9]\)$')
$ test -n "$A" && echo "matched" || echo "did not match"
matched
regards,
- assaf