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:转义字符串中的特殊字符以匹配正则表达式的主要内容,如果未能解决你的问题,请参考以下文章