我得到了一些包含正则表达式特殊控制字符的文件名。
我需要准备一个从字面上考虑所有这些字符的正则表达式。
简化的测试用例:
strFilenameOnDB="some ( file ) name +.ok";
strFilenameToCheck="$strFilenameOnDB"; #code simplification
strRegex=".*${strFilenameToCheck}.*";
if [[ "$strFilenameOnDB" =~ $strRegex ]];then echo OK;fi
以上将(当然)失败。
在 perl 中,我们可以使用 /Q /E ( https://stackoverflow.com/a/3971923/1422630 ) 将扩展的 $strRegex 转换为文字,对于 bash 有没有类似的东西?
Obs.:我会发布我已经在做的事情,但我想知道是否有更好的方法?
就个人而言,我不会将您希望作为文字的字符串与您希望被解释为正则表达式模式的正则表达式位结合起来。表达式的文字字符串位应该用双引号引起来,需要解释为正则表达式的位不应该是。
但是在这种情况下,由于正则表达式默认情况下不会锚定到字符串的开头或结尾(与始终匹配完整字符串的文件名通配模式不同),因此您可以完全不使用侧翼
.*
。您是否只是想查看文件名是否包含特定的子字符串?因为如果您使用 来执行此操作
[[ =~ ]]
,则不需要前导部分和尾随.*
部分:正则表达式匹配更像是search,它足以在字符串中的任何位置找到匹配项。此外,在 Bash 中,引用(部分)模式(或包含模式的变量)会删除引用字符的特殊含义。因此,例如,这将匹配:
虽然这没有(加号现在很特殊,并且与自身不匹配):
相比之下,非正则表达式匹配需要与整个字符串匹配,因此您需要前导和尾随
*
:在 Bash 的
=~
匹配运算符中,正则表达式中的文字字符串可以通过将它们放在双引号内来指定。所以理论上你只需要把 Perl 的 \Q 和 \E 分别变成一个双引号。
但是,如果您的要求是使用部分可变(即包含要扩展的其他 shell 变量)和部分文字的正则表达式,并且它本身包含在 shell 变量中,那么恐怕唯一的出路是也可以使用
eval
.也就是说,您的示例代码将变成这样:
总而言之,为了将文字字符串嵌入到 shell 变量中包含的部分变量正则表达式中,您需要:
\"
and another\"
代替 Perl 的 \Q 和 \Eeval
所有这一切都是为了首先扩展包含正则表达式的字符串,以便
"
shell 变量中的两个被认为是正则表达式的文字部分的开始结束,而不是通常的 Bash 引用字符,然后是整个匹配操作在这样的结果模式上执行。(当您必须在双引号 shell 变量中的正则表达式中包含双引号或反斜杠时,一项艰巨的任务就来了。)
作为旁注,您实际上并不需要
.*
正则表达式的开头和结尾,因为它们通常隐含在 Bash 的正则表达式操作中。实际上,当您不想在正则表达式之前和之后暗示其他字符时,您宁愿需要显式指定起始锚点 (^
and )。$
我以这种方式更改匹配器: