bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Conditional Regexp matching problem in 3.2


From: Ryan Waldron
Subject: Re: Conditional Regexp matching problem in 3.2
Date: Tue, 23 Jan 2007 10:23:43 -0600 (CST)

On Tue, 23 Jan 2007, Chet Ramey wrote:

rew@erebor.com wrote:
Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -g -O2
uname output: Linux kansas 2.4.18-26.7.x #1 Mon Feb 24 10:15:02 EST 2003 i686 
unknown
Machine Type: i686-pc-linux-gnu

Bash Version: 3.2
Patch Level: 0
Release Status: release

Description:
        A simple regexp match using =~ inside [[ ]] works on 3.0.16
        and 3.1 versions of bash, but doesn't in 3.2.

        In pre-3.2 versions, the script in "Repeat-By" (below)
        produces one line of output: "Dog 01 is Wiggles".  In 3.2, the
        regexp no longer matches, so it produces nothing.

Repeat-By:
        # run this, eh?
        DOG="Dog name - 01 - Wiggles"
        if [[ $DOG =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
        then
           echo Dog ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]}
        fi

One of the changes between bash-3.1 and bash-3.2 was to unify the handling
of the pattern in the `==' and `=~' conditional command operators.  Pattern
characters on the rhs are quoted to represent themselves (remove their
special pattern meaning).  This is how == has always worked.  If you remove
the double quotes and use backslashes to escape the spaces in the pattern,
you will get the match you want.

Hi, Chet.  Thanks for the explanation.  I see the value in making ==
and =~ behave the same.  However, we seem to have lost the ability to
use groupings to store results in BASH_REMATCH.

Escaping the spaces in the pattern doesn't work (though it does change
the error).  I had actually tried that (in fact, I had tried every way
of escaping that pattern that I could think of) before sending in the
bashbug.

Using this pattern (spaces backslashed, double quotes removed):

  if [[ $DOG =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]


Yields this;

================================================================
D:/tmp $ ~/src/bash-3.2/bash ./reduce.sh
Dog 01 is Wiggles
./reduce.sh: line 8: unexpected argument `(' to conditional binary
operator
./reduce.sh: line 8: syntax error near `(['
./reduce.sh: line 8: `if [[ $DOG =~ ([[:alpha:][:blank:]]*)-\
([[:digit:]]*)\ -\ (.*)$ ]]'
================================================================

If I remove the grouping parens and leave the spaces escaped, like so:

  if [[ $DOG =~ [[:alpha:][:blank:]]*-\ [[:digit:]]*\ -\ .*$ ]]

then I get a match, but $BASH_REMATCH is empty (since no groupings
were stored away):

================================================================
D:/tmp $ ~/src/bash-3.2/bash ./reduce.sh
Dog 01 is Wiggles
Matched, anyway
Dog is
================================================================


If I then also backslash-escape the parens, like so:

  if [[ $DOG =~ \([[:alpha:][:blank:]]*\)-\ \([[:digit:]]*\)\ -\ \(.*\)$ ]]

then I no longer get the error, but the pattern doesn't match any more
at all.

================================================================
D:/tmp $ ~/src/bash-3.2/bash ./reduce.sh
Dog 01 is Wiggles
================================================================

So I still can't see how to get not just a match, but a match with
grouping, to work in 3.2 without putting the pattern into an
intermediate variable.

--
Ryan Waldron    |||   http://www.erebor.com    |||    rew@erebor.com

"The web goes ever, ever on, down from the site where it began..."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]