bash变量和regex比较

bash变量和regex比较,regex,bash,variables,puzzle,Regex,Bash,Variables,Puzzle,让x='abc.xyz'和y='abc:xyz'保持以下值(打印“匹配”和“差异”): 现在,可以提取literall=“.xyz”,测试仍然有效(注意lrefs周围的双引号): 问题是:如果我们进一步尝试r=“abc\”${l}\”或r=“abc${l}”,则第一个测试永远不会打印“匹配”: 要通过这两个测试,正确的r形式应该是什么?shell通常从命令行中删除所有未引用的“(它们控制 仅当参数是否应拆分时),但 是在=~之后的特殊处理。引号在这里像转义符一样工作, 引号之间的所有内容仅作为匹

x='abc.xyz'
y='abc:xyz'
保持以下值(打印“匹配”和“差异”):

现在,可以提取literal
l=“.xyz”
,测试仍然有效(注意
l
refs周围的双引号):

问题是:如果我们进一步尝试
r=“abc\”${l}\”
r=“abc${l}”
,则第一个测试永远不会打印“匹配”:


要通过这两个测试,正确的
r
形式应该是什么?

shell通常从命令行中删除所有未引用的
(它们控制 仅当参数是否应拆分时),但 是在
=~
之后的特殊处理。引号在这里像转义符一样工作, 引号之间的所有内容仅作为匹配的原始字符处理 本身(除了仍然有效的
$
变量替换之外)

模式只有一个评估,因此引用 隐藏在变量中的变量被视为常规引号,并且 不触发特殊的引号语法

您需要转义
(或任何其他活动的)字符
$l
引号语法在变量中不起作用

如果
$l
始终等于
.xyz
,则可以使用
r=“abc\\\${l}”
获得正确的匹配。
它等于
r='abc\.xyz'

\`放入
r`赋值中是非常奇怪的(因为它假定知道
l
的内容)。我想应该放在
l
中。@Etan Reisner-你是对的,但这是一个变通办法,绝对不是一个优雅的解决方案-可以引用
l
中的所有元字符。类似
${l/././\.}
的东西在特殊情况下会起作用
l=“.xyz”
。在一般情况下(例如
l
只在运行时已知)括号、括号等应该以同样的方式处理。它应该是一种
function quote()…
并从代码中调用。@jofel-有比引用
l
中的所有元字符更好的方法。根据文档
可以引用模式的任何部分,以强制将引用部分作为字符串进行匹配。
它适用于模式
abc.xyz>,它适用于
abc${l}“
,真正的痛苦是引入
r
并随后取消引用。@j.l.谢谢,我扩展/重写了我的答案。我不认为模式被重新评估,即变量中的引号起作用。@jofel请注意
l
可以是任何东西(即使它来自stdin或类似的东西,也不知道)。一种解决方案(您介绍的)是引用
l
中的所有元字符,即使用
${l/…}
而不是
${l}
。其次,优雅的方法是将整个
${l}
视为文字序列。在bash中,它在任何模式子区域上使用双引号都得到了很好的支持。最困难的部分是[[]]内置上下文中的变量扩展:无论是
r=“abc\”${l}\
还是
r=“abc${l}”
还是
r=“abc”${l}\”
都不起作用。对于me@anubhava不,没有。这是一个微妙的bash问题当然是,
[[ "${x}" =~ abc".xyz" ]] && echo "matches"
[[ "${y}" =~ abc".xyz" ]] || echo "diff"
[[ "${x}" =~ abc"${l}" ]] && echo "matches"
[[ "${y}" =~ abc"${l}" ]] || echo "diff"
[[ "${x}" =~ ${r} ]] && echo "matches"
[[ "${y}" =~ ${r} ]] || echo "diff"