I defined a function that prints yes
if its first argument contains a
, b
or c
:
$ func() { [[ $1 =~ [abc] ]] && echo yes; }
$ func xyz
$ func xaz
yes
$ func xbz
yes
$ func xcz
yes
Now I would like to detect [
, ]
or *
so I tried:
func() { [[ $1 =~ [\[\]*] ]] && echo yes; }
$ func x*z
$ func x[z
$ func x]z
yes
This is only seems to work for ]
. I also tried set -f
to disable glob expansion but got same results.
The behavior is very well explained in BRE/ERE Bracketed Expression section of POSIX regex specification:
- [...] The right-bracket (
']'
) shall lose its special meaning and represent itself in a bracket expression if it occurs first in the list (after an initial circumflex ('^'
), if any). Otherwise, it shall terminate the bracket expression, unless it appears in a collating symbol
Which means, your ]
needs to be present in your bracket expression at the beginning, may be after a ^
, and not anywhere later in the expression. This is a special case that applies only for ]
but not for [
which loses its special character inside a bracket expression.
So defining
[[ $1 =~ [][*] ]]
should work as expected, because ]
at the beginning is not terminating the bracket expression. Disabling glob expansion is of no consequence here, as *
inside a bracket expression does not have a special meaning and only treated literally.