如何在 bash 中使用正则表达式匹配大写和小写字母?

如何在 bash 中使用正则表达式匹配大写和小写字母?

我们设置以下变量

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,因此OK

对于正则表达式,您需要使用^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语法。

zshshell 中,您可以使用扩展的通配符或 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,您需要避免使用名为$statusas 的变量,该变量保存前一个命令的退出状态作为 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"

相关内容