【问题标题】:Perl: Escape special chars in a string to match a regexPerl:转义字符串中的特殊字符以匹配正则表达式
【发布时间】: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 函数中复制粘贴了它...

标签: regex perl escaping special-characters


【解决方案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
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
  • 2011-11-17
  • 1970-01-01
  • 2011-08-21
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多