简体   繁体   English

Perl:转义字符串中的特殊字符以匹配正则表达式

[英]Perl: Escape special chars in a string to match a regex

I'm writing bash functions to handle string operations with regexes. 我正在编写bash函数以使用正则表达式处理字符串操作。 Bash built-in functions being very poor at the job, I'm using the perl command to do it. Bash内置函数在工作中非常差,我正在使用perl命令来完成它。

For instance, here's my "strMatch" function (in bash): 例如,这是我的“ strMatch”函数(以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". 测试字符串: foo-bar\\rLoading... xx%\\rFile: "some-(filename.ext".
regex: -bar(?:.*?)File: "(.\\*?)\\.ext" 正则表达式: -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. 我是Perl的新手(除了regex语法),所以我尝试了到处都是的各种尝试,但都没有成功。

with 'qq' it doesn't handle '(', which is interpreted as a capturing group without a matching ')'. 如果使用'qq' ,则不会处理'(',这被解释为没有匹配的')'的捕获组。 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) { " => -e第1行的语法错误,靠近“ qq(foo-bar \\ rLoading ... xx%\\ rFile:“ some-(filename.ext”。)=〜m / -bar \\ r(?:。* ?)文件:“(。*?)\\。ext” / g){“
=> Can't find string terminator ")" anywhere before EOF at -e line 1. =>在-e第1行EOF之前的任何位置都找不到字符串终止符“)”。

with 'quotemeta' it's worse, breaks at ':', '%', '\\r'... pretty much everything 使用'quotemeta'会更糟,在':','%','\\ r'处中断...
=> Backslash found where operator expected at -e line 1, near "bar\\" =>反斜杠在-e行1的“ 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!!! 作为奖励,如果我添加'w'或'W'选项以获得perl警告,它不会输出任何内容!!! 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 ? 我只希望字符串能够包含几乎所有内容,包括'%','((','[','\\ r','\\ n'......有人知道该怎么做吗?做错了吗?

EDIT: Answered 编辑:回答

Thank you choroba , using perl arguments $ARGV works like a charm. 谢谢choroba ,使用perl参数$ ARGV就像一个魅力。 I also used a modified version of ikegami 's solution which is more elegant. 我还使用了更美观的ikegami解决方案的修改版本。

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. Edit2:添加了“-”以停止处理选项。

Pass the string and regex as parameters (I also simplified the Perl code): 将字符串和正则表达式作为参数传递(我也简化了Perl代码):

#!/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"'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM