Bash中不区分大小写的正则表达式

Osc*_*vis 4 regex bash case-insensitive

我想知道哪种方法更好地检查var(由用户在键盘上输入)是否以不区分大小写的方式与正则表达式匹配。我知道有一些不同的可能性。例如:我想一个正则表达式匹配一个空值,而这一切的名单:YNynYesNoYESNO

我搜索了不同的方法。不知道是否会更好。我会把其中的一些给我工作。

  • 第一个是将所有内容都设置为大写的“ tricky”设置,以进行比较:

    #!/bin/bash
    yesno="null" #any different value for initialization is valid
    while [[ ! ${yesno^^} =~ ^[YN]$|^YES$|^NO$|^$ ]]; do
        read -r yesno
    done
    
    Run Code Online (Sandbox Code Playgroud)
  • 第二个是使用shopt -s nocasematch。但是不确定这样做之后是否可以还原,因为我不想为所有脚本设置它。

    #!/bin/bash
    yesno="null" #any different value for initialization is valid
    shopt -s nocasematch
    while [[ ! ${yesno} =~ ^[yn]$|^yes$|^no$|^$ ]]; do
        read -r yesno
    done
    
    Run Code Online (Sandbox Code Playgroud)

这些正则表达式能否以任何方式得到改进?有没有更好(更优雅)的方法?在第二种方法上,有没有办法还原该设置?

anu*_*ava 12

shopt是一种很好的方法,因为您可以在变量中保留最初输入的值yesno

您可以稍微重构一下正则表达式:

#!/bin/bash

yesno="null"

# set nocasematch option
shopt -s nocasematch

while [[ ! ${yesno} =~ ^([yn]|yes|no)?$ ]]; do
    read -r -p "Enter a yes/no value: " yesno
done

# unset nocasematch option
shopt -u nocasematch

# examine your variable
declare -p yesno
Run Code Online (Sandbox Code Playgroud)


pyn*_*exj 6

您可以先将字符串转换为小写形式并进行检查。然后,您根本不需要触摸nocasematch。变量的内容也保持不变。

# use the ${var,,} syntax to conver to lowercase
while [[ ! ${yesno,,} =~ ^(y|n|yes|no)$ ]]; do
    read -r -p "yes/no? " yesno
done
Run Code Online (Sandbox Code Playgroud)

  • 这看起来比`shopt`方式更优雅。 (3认同)
  • 您可能应该补充一点,这不符合 posix 标准,并且需要 bash >= 4.0.0 (3认同)
  • 如果您需要在多单词用户输入中进行检查,您可能需要单词边界和任何字符检查才能使其正常工作。我挣扎了很长时间,因为它会给像“ye s”这样的东西带来错误的结果。也许需要这样的东西。`^.*\b(y|n|是|否)\b.*$` (2认同)