Reputation: 13
I'm writing bash functions to handle string operations with regexes. Bash built-in functions being very poor at the job, I'm using the perl command to do it.
For instance, here's my "strMatch" function (in bash):
# Usage: if (strMatch <string> <regex>); then...
function strMatch {
local str="$1"
local regex="$2"
local perlCmd='if (qq('$str') =~ m/'$regex'/g) { print "0"; } else { print "1"; }'
return $(perl -e "$perlCmd")
}
Test string: foo-bar\rLoading... xx%\rFile: "some-(filename.ext".
regex: -bar(?:.*?)File: "(.\*?)\.ext"
Everything works fine except for one thing ; I can't find a way to properly escape special chars within the string to match (for some of them, at least).
I'm very new to Perl (except for regex syntax), so I tried various things found here and there without any success.
with 'qq' it doesn't handle '(', which is interpreted as a capturing group without a matching ')'. I'm guessing the same will happen with '['...
=>
syntax error at -e line 1, near "qq(foo-bar\rLoading... xx%\rFile: "some-(filename.ext".) =~ m/-bar\r(?:.*?)File: "(.*?)\.ext"/g) { "
=>
Can't find string terminator ")" anywhere before EOF at -e line 1.
with 'quotemeta' it's worse, breaks at ':', '%', '\r'... pretty much everything
=>
Backslash found where operator expected at -e line 1, near "bar\"
=>
Operator or semicolon missing before %
As a bonus, if I add 'w' or 'W' option to get perl warnings, it doesn't print anything!!! what's going on?
I just want the string to be able to contain pretty much anything including '%', '(', '[', '\r', '\n'... Anyone know how to do that??? What am I doing wrong ?
EDIT: Answered
Thank you choroba, using perl arguments $ARGV works like a charm. I also used a modified version of ikegami's solution which is more elegant.
Function now goes like this:
# Usage: if (strMatch <string> <regex>); then...
function strMatch {
local str="$1"
local regex="$2"
local perlCmd='exit 1 if ($ARGV[0] !~ m/$ARGV[1]/g)'
perl -e "$perlCmd" "--" "$str" "$regex"
return $?
}
Edit2: Added "--" to stop processing options.
Upvotes: 1
Views: 1020
Reputation: 241878
Pass the string and regex as parameters (I also simplified the Perl code):
#!/bin/bash
# Usage: if (strMatch <string> <regex>); then...
function strMatch () {
local str="$1"
local regex="$2"
local perlCmd='print $ARGV[0] =~ m/$ARGV[1]/ ? 0 : 1'
return $(perl -e "$perlCmd" "--" "$str" "$regex")
}
Tested with
~/test.sh $'foo-bar\rLoading... xx%\rFile: "some-(filename.ext"' '-bar(?:.*?)File: "(.*?).ext"'
Upvotes: 1