'Case insensitive regex in Bash

I want to know which method is better to check if a var (input by user on keyboard) matches with a regex in a case insensitive way. I know there are some different possibilities. Example: I want a regex matching an empty value and all of this list: Y, N, y, n, Yes, No, YES, NO

I searched looking different methods. Not sure if could be another better. I'll put a couple of them working for me.

  • First one is a little "tricky" setting all to uppercase for the comparison:

    #!/bin/bash
    yesno="null" #any different value for initialization is valid
    while [[ ! ${yesno^^} =~ ^[YN]$|^YES$|^NO$|^$ ]]; do
        read -r yesno
    done
    
  • Second one is using shopt -s nocasematch. But not sure if after doing that it can be reverted because I don't want to set this for all the script.

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

Can these regex get improved in any way? Is there a better (more elegant) method? On second method, is there a way to revert that setting?



Solution 1:[1]

You can first convert the string into lowercase and check it. Then you don't need to touch nocasematch at all. The content of the variable is left unmodified as well.

#
# NOTE: This requires Bash 4.0+ (bash 4.0 was released on 2009-02-20)
#
# use the ${var,,} syntax to convert to lowercase
#
while [[ ! ${yesno,,} =~ ^(y|n|yes|no)$ ]]; do
    read -r -p "yes/no? " yesno
done

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 declension