15

so I have this function

function test(){
 local output="CMD[hahahhaa]"
 if [[ "$output" =~ "/CMD\[.*?\]/" ]]; then
  echo "LOOL"
 else
  echo "$output"
 fi;

}

however executing test in command line would output $output instead of "LOOL" despite the fact that the pattern should be matching $output...

what did I do wrong?

pillarOfLight
  • 8,592
  • 15
  • 60
  • 90
  • Are you trying to use `.*?` as a non-greedy match? `bash` does not support that Perl-style operator. The forward slashes are also part of Perl's matching syntax, not part of a regular expression itself. – chepner Oct 12 '13 at 17:57

1 Answers1

35

Don't use quotes ""

if [[ "$output" =~ ^CMD\[.*?\]$ ]]; then

The regex operator =~ expects an unquoted regular expression on its RHS and does only a sub-string match unless the anchors ^ (start of input) and $ (end of input) are also used to make it match the whole of the LHS.

Quotations "" override this behaviour and force a simple string match instead i.e. the matcher starts looking for all these characters \[.*?\] literally.

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
  • This doesn't actually work though, right? Bash doesn't support the lazy modifier. – Michael Wu Aug 07 '17 at 22:01
  • 1
    I have lost hours debbuging a single line in my script due to this behavior of [['s regex. At first glance, the same result would be got using '...'. What would be de motivation to do that, i.e., to give single quoted power to double quote strings? I can't realize such logic behind. I found this "inscripition" in bash manual: "Word splitting and pathname expansion are not performed on the words between the [[ and ]];..." Would it be a clue? – Daniel Bandeira Jan 27 '20 at 23:41