3

The follow code with a regular expression check does not outputs the same result between bash 3 and bash 4:

TESTCASE="testcase0"
[[ ${TESTCASE} =~ "^testcase[0-9\.]*$" ]]
echo $?
echo ${BASH_REMATCH}

bash 3.2 outputs a successful regular expression check:

0
testcase0

bash 4.1 fails the regular expression check:

1
<empty line>

I can't identify where in my regex pattern the expressions fails. I would need a code compatible between both version of bash.

Does anyone have a clue on what's my problem ?

Thanks !

LAL
  • 480
  • 5
  • 13

1 Answers1

9

In older versions of Bash (3.1), it was possible to use quotes around a regular expression in a test. In newer versions, the quotes are treated as part of the pattern, so the match fails.

The solution is to remove the quotes.


The recommended way to use regular expressions is this:

re='^testcase[0-9\.]*$'  # single quotes around variable
[[ ${TESTCASE} =~ $re ]] # unquoted variable used in test

This syntax should work in all versions of bash that support regular expressions. The variable isn't strictly necessary but it improves readability. See the regular expressions section of Greg's wiki for more details.

Regarding the use of a variable (from the link above):

For cross-compatibility (to avoid having to escape parentheses, pipes and so on) use a variable to store your regex, e.g. re='^\*( >| *Applying |.*\.diff|.*\.patch)'; [[ $var =~ $re ]] This is much easier to maintain since you only write ERE syntax and avoid the need for shell-escaping, as well as being compatible with all 3.x BASH versions.

By the way, there's no need to escape the . inside the bracket expression.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141