$ man bash
Word splitting and filename expansion are not performed on the words between the ‘[[’ and ‘]]’; tilde expansion, paramete
[[ ... ]]
is not POSIX syntax, but an extension that is found in the Korn shell. Bash does it the way the Korn shell does it, because doing it differently would just be incompatible for no reason.
From Korn Shell 93 man page:
Conditional Expressions
A conditional expression is used with the [[ compound command to test attributes of files
and to compare strings. Field splitting and file name generation are not performed on the
words between [[ and ]]. Each expression can be constructed from one or more of the
following unary or binary expressions:
http://www2.research.att.com/sw/download/man/man1/ksh.html
So why does the Korn shell do it that way? 1) Who cares; 2) E-mail Dave Korn. 3) Maybe the answer is found in some document at http://www.kornshell.com . But think about this: if the field splitting and file expansion were performed, how would this construct be different from [ ... ]
?
Check your bash version. Starting from version 3.2 this behavior was added that states:
Quoting the string argument to the [[ command's =~ operator now forces string matching, as with the other pattern-matching operators.
I guess you are using bash >= ver 3.2 for your test.
That's the reason when you quote the regular expression it is doing plain simple string matching instead of regex matching.
Update: If you want regex matching inside double quotes then use:
shopt -s compat31
As per the manual:
compat31
If set, bash changes its behavior to that of version 3.1 with respect to quoted arguments to the conditional command's =~ operator.
which causes your command to behave differently:
[[ "hello" =~ "he.*" ]] && echo YES || echo NO
YES
This is not the behavior I would have expected either. However, I do not believe it is due to the man page entry you've cited, but rather due to the behavior of =~.
My guess is that " is interpreted as a literal character in the Extended Regular Expression.
For example,
[[ hello = "hello" ]] && echo YES || echo NO
YES
So the double quotes are ordinarily stripped.
Consider also grep, on the shell:
echo foo | grep '"foo"' && echo YES || echo NO
Versus:
echo foo | grep "foo" && echo YES || echo NO
foo
YES
In this case, "s are removed by the shell before grep receives them. In the latter case, grep receives the quote, and the regular expression engine determines it not to be a match.
I posit that precisely this is the case for =~.