【问题标题】:Bash variable substitution with a regex not working as expected使用正则表达式替换 Bash 变量未按预期工作
【发布时间】:2018-01-31 12:34:34
【问题描述】:

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

INPUT="Cookie: cf_clearance=foo; __cfduid=bar;"

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

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

我在这里做错了什么?

【问题讨论】:

  • 谁告诉你 bash 支持 RegEx 的内置字符串替换???
  • @iBug 但据我所知确实如此。像${MYVAR//[a-z]/X} 这样更简单的模式可以工作。
  • 那不是正则表达式。它只是一个括号表达式,甚至被 printf()scanf() 支持(如果您编写 C 程序)。
  • 谢谢,现在我明白我的期望是错误的。直到!

标签: regex bash substitution


【解决方案1】:

使用实际的正则表达式匹配功能而不是参数扩展,这适用于模式。

[[ $INPUT =~ (.*)(cf_clearance=[^;]*;)(.*) ]]
ans=${BASH_REMATCH[1]}${BASH_REMATCH[3]}

你也可以使用扩展模式,相当于power中的正则表达式:

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

【讨论】:

  • 我认为这是正确的答案。请注意,这两个选项都是 bash-only;它们无法在其他 shell 中工作(例如 Ubuntu 的 dashkshzsh 等)。这个问题是特定于 Bash 的,所以这不是这个答案的问题;重要的是要注意。
  • 它也不适用于 Python、Perl、Haskell、Ruby 或任何数量的其他语言;你要注意吗? kshzsh 有可用的解决方案(可能与 bash 解决方案没有太大区别),而 POSIX shell 需要多次使用 expr 命令。
  • 我并不是要批评这个答案;我认为这是好的和正确的。我指出了其他 shell 的不兼容性,因为“bashisms”是 shell 编码初学者的常见混淆来源。这只是需要注意的事情;这个问题是关于 Bash 的,你的答案是 100% 正确的。
【解决方案2】:

使用sed:

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

【讨论】:

  • 谢谢。我知道我可以使用 sed 甚至 awk,但我想了解为什么 bash 替换在这种情况下不起作用。
  • @oscahie AFAIK Bash 不支持带有内置替换的正则表达式。只有通配符。
  • 我在怀疑我应该接受哪个答案。 TBH 这是一种非常直接和简单的方法,也非常有效。
  • @oscahie 由您决定接受哪一个。随着您在 Stack Overflow 上的参与越多,您将面临更多类似的情况,所以不要太在意。选择你喜欢的并继续前进。干杯
【解决方案3】:

就像您在 cmets 中被告知的那样,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=*;}"

不过,即使对于我的复杂口味,这也有点浓。)

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 2022-01-02
    相关资源
    最近更新 更多