我们设置以下变量
status=ok
echo $status
ok
现在我们要验证正则表达式的变量是否匹配
如下
[[ $status =~ [OK] ]] && echo "is the same"
[[ $status =~ OK ]] && echo "is the same"
[[ $status =~ "OK" ]] && echo "is the same"
但以上任何一个都不会打印“是相同的”
我的正则表达式出了什么问题?
答案1
[OK]
将匹配括号内的任一字符,括号并不告诉它不区分大小写。
你可以这样做:
[[ "$status" =~ ^[Oo][Kk]$ ]]
或者我可能会执行以下操作:
[[ "${status,,}" == ok ]]
参数扩展运算符,,
会将整个变量转换为小写,以便进行比较。
答案2
[[ $status =~ OK ]]
(或[[ $status =~ "OK" ]]
) 匹配如果$status
包含 OK
,并且[[ $status =~ [OK] ]]
如果满足则匹配包含该集合中的一个字符OK
,因此O
或K
。
对于正则表达式,您需要使用^
or$
来锚如果您想将主题作为一个整体而不是在其中进行匹配,则分别在主题的开头和结尾处使用模式。
要在 中进行不区分大小写的匹配bash
,您可以使用以下nocasematch
选项:
这适用于与 Korn 风格[[ $var = pattern ]]
或标准匹配的 shell 模式case $var in (pattern)
以及与[[ $var =~ regexp ]]
.
所以,在这里你可以这样做:
shopt -s nocasematch
[[ $status = ok ]] && echo yes
[[ $status =~ ^ok$ ]] && echo yes
case $status in
(ok) echo yes
esac
(您可能希望nocasematch
随后取消设置或将其重置为之前的值(请参阅typeset restore="$(shopt -p nocasematch)"
保存和eval "$restore"
恢复),因为保留它会影响所有模式匹配操作)。
或者你可以使用:
[[ $status = [oO][kK] ]] && echo yes
[[ $status =~ ^[oO][kK]$ ]] && echo yes
case $status in
([oO][kK]) echo yes
esac
case $status in
(ok | OK | Ok | oK) echo yes
esac
其case
基础变体是标准 POSIXsh
语法。
在zsh
shell 中,您可以使用扩展的通配符或 PCRE 正则表达式运算符来选择性地为单个模式或单个模式的一部分启用不区分大小写的匹配,而不是nocasematch
全局打开全局选项(并破坏所有模式匹配运算符)。
例如,
set -o extendedglob
[[ $status = (#i)ok ]]
或者:
zmodload zsh/pcre
[[ $status -pcre-match '^(?i)ok$' ]]
bash
或者,对于s的等效项${var,,}
,请使用$var:l
à la csh 或${(L)var}
:[ "$status:l" = ok ]
在 中zsh
,您需要避免使用名为$status
as 的变量,该变量保存前一个命令的退出状态作为 Bourne 样式的别名,$?
就像大多数非 Bourne shell(csh、tcsh、rc、es、fish至少)。
在 Korn shell 的 ksh93 变体中([[...]]
bash 和 zsh 都已复制),您可以执行[[ $status = ~(i)ok ]]
.
答案3
你可以像这样进行模式匹配:
[[ $status == @(ok|OK|okay) ]] && echo "is the same"
或者,与上一篇文章中 jesse_b 的想法类似,^^
参数扩展运算符会将整个变量转换为大写,以便进行比较:
[[ "${status^^}" == OK ]] && echo "is the same"