Regex 带有正则表达式的Bash变量替换未按预期工作

Regex 带有正则表达式的Bash变量替换未按预期工作,regex,bash,substitution,Regex,Bash,Substitution,给定一个包含以下字符串的bash变量: INPUT="Cookie: cf_clearance=foo; __cfduid=bar;" 为什么替换${INPUT/cf_clearance=[^;]*;/}产生输出:Cookie:而不是我期望的:Cookie:\uu cfduid=bar 在在线正则表达式验证器中测试同一正则表达式确认cf_clearance=[^;]*应匹配cf\u clearance=foo仅,而不是字符串的其余部分 我做错了什么?使用sed: INPUT

给定一个包含以下字符串的bash变量:

INPUT="Cookie: cf_clearance=foo; __cfduid=bar;"
为什么替换
${INPUT/cf_clearance=[^;]*;/}
产生输出:
Cookie:
而不是我期望的:
Cookie:\uu cfduid=bar

在在线正则表达式验证器中测试同一正则表达式确认
cf_clearance=[^;]*应匹配
cf\u clearance=foo仅,而不是字符串的其余部分

我做错了什么?

使用
sed

INPUT=$(sed 's/cf_clearance=[^;]*;//' <<< "$INPUT")

INPUT=$(sed's/cf_clearance=[^;]*;/”使用实际的正则表达式匹配功能,而不是使用模式的参数扩展

[[ $INPUT =~ (.*)(cf_clearance=[^;]*;)(.*) ]]
ans=${BASH_REMATCH[1]}${BASH_REMATCH[3]}
您还可以使用扩展模式,它相当于power中的正则表达式:

shopt -s extglob
$ echo "${INPUT/cf_clearance=*([^;]);/}"

正如在评论中告诉您的那样,bash参数替换只支持glob模式,而不支持正则表达式。因此,问题实际上在于您的期望,而不是您的代码本身

如果知道表达式可以锚定到字符串的开头,则可以使用
${INPUT#prefix}
参数替换来获取尽可能短的匹配,并在前面添加
Cookie:

echo "Cookie: ${INPUT#Cookie: cf_clearance=*;}"
如果您没有这个保证,可以用一对参数替换来近似类似的东西。找到
cf_clearance
前面的部分,找到
cf_clearance
后面的分号后面的部分,将它们粘在一起

head=${INPUT%cf_clearance=*}
tail=${INPUT#*cf_clearance=*;}
echo "$head$tail"
(如果您不害怕复杂的替换,那么临时变量就不是真正必要或有用的

echo "${INPUT%cf_clearance=*}${INPUT#*cf_clearance=*;}"

即使是对我复杂的品味来说,这也有点复杂。)

谁告诉过你bash支持带有内置字符串替换的正则表达式???@iBug,但据我所知,它支持正则表达式。像
${MYVAR/[a-z]/X}
这样的简单模式可以工作。这不是正则表达式。它只是一个括号表达式,甚至得到
printf()的支持
scanf()
(如果您编写C程序)。切圆地看也谢谢,现在我看到我有错误的期望。直到!谢谢。我知道我可以使用sed甚至awk,但我想了解为什么bash替换在这种情况下不起作用。@Oschahie AFAIK bash不支持带有内置替换的正则表达式。只有通配符。我怀疑我应该接受哪个答案。这是一个退出e直截了当且简单的方法,也是非常有效的。@oscahie由您决定接受哪种方法。随着您更多地参与堆栈溢出,您将面临更多类似于此的情况,因此不要太担心。选择您喜欢的方法并继续前进。谢谢。我认为这是正确的答案。请注意,这两个选项都是bash唯一选项;而y在其他shell中不起作用(例如Ubuntu的
dash
ksh
zsh
,等等)。这个问题是特定于Bash的,因此这不是这个答案的问题;需要注意的是。它在Python、Perl、Haskell、Ruby或任何其他语言中都不起作用;您想注意吗?有针对
ksh
zsh
的解决方案可用(可能与
bash
解决方案没有太大区别),而POSIX shell需要多次使用
expr
命令。我不是要批评这个答案;我认为它是好的和正确的。我指出了其他shell的不兼容性,因为“bashisms”对于在shell中编写代码的初学者来说,这是一个常见的困惑源。这只是需要注意的一点;问题是关于Bash的,同样,您的答案是100%正确的。