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

Posted

技术标签:

【中文标题】Perl:转义字符串中的特殊字符以匹配正则表达式【英文标题】:Perl: Escape special chars in a string to match a regex 【发布时间】:2014-12-13 05:47:51 【问题描述】:

我正在编写 bash 函数来处理带有正则表达式的字符串操作。 Bash 内置函数在工作上很差,我正在使用 perl 命令来完成。

例如,这是我的“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")

测试字符串:foo-bar\rLoading... xx%\rFile: "some-(filename.ext". 正则表达式:-bar(?:.*?)File: "(.\*?)\.ext"

除了一件事,一切都很好;我找不到正确转义字符串中的特殊字符以匹配的方法(至少对于其中一些字符)。 我对 Perl 很陌生(正则表达式语法除外),所以我尝试了各种在这里和那里找到的东西,但没有任何成功。

使用 'qq' 它不处理 '(',它被解释为没有匹配 ')' 的捕获组。我猜'['也会发生同样的情况...... => -e 第 1 行的语法错误,靠近 "qq(foo-bar\rLoading... xx%\rFile: "some-(filename.ext".) =~ m/-bar\r(?:.*?)文件:"(.*?)\.ext"/g) " => 在 -e 第 1 行的 EOF 之前的任何地方都找不到字符串终止符“)”。

使用 'quotemeta' 更糟糕的是,在 ':'、'%'、'\r' 处中断...几乎所有内容 => 反斜杠在 -e 第 1 行的“bar\”附近找到操作员预期的位置 => % 前缺少运算符或分号

作为奖励,如果我添加 'w' 或 'W' 选项来获取 perl 警告,它不会打印任何内容!!!怎么回事?

我只希望字符串能够包含几乎任何内容,包括 '%'、'('、'['、'\r'、'\n'...有人知道怎么做吗???我做错了什么?

编辑:已回答

谢谢choroba,使用 perl 参数 $ARGV 就像一个魅力。我还使用了 ikegami 解决方案的修改版本,它更优雅。

功能现在是这样的:

# 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:添加“--”来停止处理选项。

【问题讨论】:

if (/.../g) 没有意义,并且可能导致细微的错误。你想要if (/.../) 我正在使用 if ($var =~ m/.../g) 。什么意思? 我不确定需要澄清什么。 删除 -- 也是一个坏主意。现在,如果要搜索的字符串以 - 开头,它将失败。 添加了双破折号。顺便说一句,您的意思是使用全局范围是无用的,因为我不关心多次出现吗?如果是这样,我知道,那是因为我从我的 strGetMatches 函数中复制粘贴了它... 【参考方案1】:

将字符串和正则表达式作为参数传递(我还简化了 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")

经过测试

~/test.sh $'foo-bar\rLoading... xx%\rFile: "some-(filename.ext"' '-bar(?:.*?)File: "(.*?).ext"'

【讨论】:

甚至不需要print: perl -e'exit 1 if $ARGV[0] !~ m/$ARGV[1]/' -- "$str" "$regex" // return $? 谢谢!那很有帮助。它有效,但如果在正则表达式中使用 '\r' 则无效。 '-bar.*?File: "(.*?)\.ext"' 有效,但不是 '-bar\r.*?File: "(.*?)\.ext"' 是的。测试:if strMatch "$( echo -e 'foo\rbar' )" 'foo\rbar' ; then echo 'match' ; else echo 'no match' ; fi 它在使用字符串文字时不起作用,但它确实适用于 -e,是的。它也适用于“\\r”。我正在更新我的原始帖子 \r 不应该匹配\ r 这两个字符;它应该与回车匹配。如果要匹配\ r,则需要模式\\r。测试:if strMatch 'foo\rbar' 'foo\\rbar' ; then echo 'match' ; else echo 'no match' ; fi

以上是关于Perl:转义字符串中的特殊字符以匹配正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式中必须转义哪些特殊字符?

正则表达式中必须转义哪些特殊字符?

正则表达式中必须转义哪些特殊字符?

正则中需要转义的特殊字符小结

Linux 正则表达

Linux 正则表达