ok I appreciate the explanation. On Wed, 29 Dec 2021 at 20:58, Paul Eggert <egg...@cs.ucla.edu> wrote:
> On 12/29/21 12:01, Martin Rixham wrote: > > What nonsense. I want to parse source code. ')' is not an uncommon line > of > > source code. It should work. > > Unfortunately, you're asking for what is in general impossible. If the > left argument of ':' could be any string, then the grammar for 'expr' > would be ambiguous. Consider the following shell command: > > expr '(' : ')' > > This outputs ':' because it evaluates the parenthesized string ':'; but > if the operands of ':' could be any strings it could also be interpreted > as matching '(' against ')', which means it should output the same thing > as 'expr a : b', namely '0'. > > Of course this means 'expr' was poorly designed in the 1970s, but we're > stuck with that design now (it's standardized by POSIX), portable code > must deal with this poor design, and for compatibility reasons it's > better for GNU expr to support the design, poor as it is. > > These days there are much better ways than 'expr' to parse code. For > example, if you want to count the number of characters in a shell > variable v, you can use this shell command: > > nv=${#v} > > This works even if v=')', whereas this: > > nv=$(expr "$v" : '.*') > > has the bug that you mentioned, plus it's harder to read and it's less > efficient. >