Bash – Forcing Bash to use Perl RegEx Engine

bashperlregular expression

As you may already know, a lot of the features modern RegEx engines support (back referencing, lookaround assertions, etc.) are not supported by Bash RegEx engine. Following is a simple Bash script I have just created to try to explain what my end goal is:

#!/bin/bash

# Make sure exactly two arguments are passed.
if [ $# -lt 2 ]
then
    echo "Usage: match [string] [pattern]"
    return
fi

variable=${1}
pattern=${2}

if [[ ${variable} =~ ${pattern} ]]
then
    echo "true"
else
    echo "false"
fi

So for instance, something like the following command will return false:

. match.sh "catfish" "(?=catfish)fish"

whereas the exact same expression will find a match when used in a Perl or a JavaScript regex tester.

Backreferences (e.g. (expr1)(expr2)[ ]\1\2) won't match as well.

I have simply come to the conclusion that my problem will only be solved when forcing bash to use a Perl-compatible RegEx engine.
Is this doable? If so, how would I go about performing the procedure?

Best Answer

Bash doesn't support a method for you to do this at this time. You're left with the following options:

  1. Use Perl
  2. Use grep [-P|--perl-regexp]
  3. Use Bash functionality to code it

I think I would go with #2 and try and use grep to get what I want functionally. For back referencing you can do the following with grep:

$ echo 'BEGIN `helloworld` END' | grep -oP '(?<=BEGIN `).*(?=` END)'
helloworld

-o, --only-matching       show only the part of a line matching PATTERN
-P, --perl-regexp         PATTERN is a Perl regular expression

(?=pattern)
    is a positive look-ahead assertion
(?!pattern)
    is a negative look-ahead assertion
(?<=pattern)
    is a positive look-behind assertion
(?<!pattern)
    is a negative look-behind assertion 

References

Related Question