Paul Jarc wrote:
It looks for substrings in both cases - specifically, the longest
matching substring, which might happen to be the entire string. With
!(), that is often the case.
x=12ab34; echo ${x//+([0-9])/X} # prints XabX
x=12ab34; echo ${x//!(+([0-9]))/X} # prints X
---
The longest matching substring (because you use "/" to start the pattern,
yes?) I'm not sure I fully understand this behavior though. Let's have
s="thomas rich george"
Manpage says "!()" will match anything except one of the patterns.
"$s" is 1 pattern, no? (no alternation); 1 pattern containing
"thomas rich george", yes?
Then if I use !($s) as the replacement pattern within in the substitute
operator, ( ${s//!($s)/X} ) the !($s) should match any string
except what is in "$s" ("thomas rich george").
So in the substitute, the string to replace (the "!($s) part) should
match nothing in my variable "$s", so I'd think no replacement would
be done. I.e. the output would be unchanged. But when I
try it that's not what I get:
echo \"${s//!($s)/X}\"
"XX" # why two X's? if I use 1 "/" instead of double:
echo \"${s/!($s)/X}\"
"Xe" # why an "e" afterwards?
-----
The converse works as expected:
echo \"${s//+($s)/X}\"
"X"
echo \"${s/+($s)/X}\"
"X"