bug-bash
[Top][All Lists]
Advanced

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

Re: capturing sub-expressions?


From: Bernd Eggink
Subject: Re: capturing sub-expressions?
Date: Tue, 29 Jan 2008 22:20:08 +0100
User-agent: Thunderbird 2.0.0.9 (X11/20071031)

Pierre Gaston schrieb:
On Jan 28, 2008 4:00 AM, Linda Walsh <bash@tlinx.org> wrote:
I was wondering -- in the bash substitute commands ${..%%|##|//} etc,
is there a way to "capture" a subexpression, so that I can
use the subexpression in the replacement string so I can
end up 'only' with the the subexpression?

I don't think so, you can only use =~ and BASE_REMATCH

If the full expression was in a shellvar "Options", I thought about
using something like:
     ${Option//!(expr)}
which I hoped would have "!(expr) match anything but my desired
expression, and the double "/" would say allow it to match multiple
times, but it appears the "!()" construct is limited to pathname
expansion?  Presuming that is true (limited to pathname expansion),
is there anyway to do it on Shell vars?

!( ) is indeed not very intuitive, it is not limited to pathname
expansion but it is not as interesting as it might seem.

!(expr) will match anything that is not expr, for instance !(foo) will
match f  and bar, but it also  match "fooa",
the only thing that is not match is  exactly "foo", which is useful if
you do: "echo !(foo)" to list all the files except
the one named "foo".

Now if you use parameter expansion :
var=fooa;echo ${var//!(foo)/b} # prints "b" because !(foo) matches "fooa"
var=foo; echo ${var/!(foo)/b} # prints "bo" because !(foo) matches "fo"
var=foo; echo ${var/!(foo)/b} # prints "bb" because !(foo) matches "fo" and "o"

My impression is that the pattern lookup depends on whether or not a '!' is involved. If the pattern does not contain a '!', the shell looks for matching substrings, from left to right. If it contains a '!', the value as a whole is matched.
Example:

    x=12ab34; echo ${x//+([0-9])/X}        # prints XabX
    x=12ab34; echo ${x//!(+([0-9]))/X}     # prints X

If the same algorithm had been applied in the 2nd case, the first substring matching the pattern "not a sequence of at least one digit" would have been 'a' (or maybe 'ab'), and the output would have been '12Xb34' (or '12X34').

IMHO (please correct me if I'm wrong) this contradicts the usual meaning of the '!' operator and makes it nearly useless - except in the simple "echo !(foo)" case you mentioned.

Bernd

--
Bernd Eggink
monoped@sudrala.de
http://sudrala.de




reply via email to

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