将数字与全局模式匹配

Ver*_*era 2 bash wildcards

我正在尝试使用全局模式进行匹配。然而,这场比赛失败了:

dgt='^+([0123456789])$'
[[ "$1" == $dgt  ]] && echo "SUCCESS" || echo "FAILURE"
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 6

您的模式^+([0123456789])$是扩展的通配模式和正则表达式的混合。通配模式不需要显式锚定,因为无论如何它总是锚定的。^因此,以 开头和结尾的通配模式$将匹配字符串开头和结尾的那些文字字符。如果您想使用通配模式并且不想^在开头和$结尾进行匹配,请删除它们。

您最终将得到以下代码:

#!/bin/bash

# Bash releases earlier than 4.1 needs to enable the extglob shell
# option.  For release 4.1+, the pattern used in [[ ]] is assumed
# to be an extended globbing pattern.
#
# shopt -s extglob

pattern='+([0123456789])'

if [[ $1 == $pattern ]]; then
   echo 'contains only digits'
else
   echo 'contains non-digit or is empty'
fi
Run Code Online (Sandbox Code Playgroud)

在没有扩展通配模式的 shell 中,匹配非数字会更容易:

#!/bin/sh

case $1 in
    *[!0123456789]*)
        echo 'contains non-digit' ;;
    '')
        echo 'is empty' ;;
    *)
        echo 'contains only digits'
esac
Run Code Online (Sandbox Code Playgroud)

bashshell 中,您也可以使用上面的代码,因为它是可移植的并且可以在所有sh兼容的 shell 中工作,或者您可以使用

#!/bin/bash

pattern='*[!0123456789]*'

if [[ $1 == $pattern ]]; then
   echo 'contains non-digit'
elif [ -z "$1" ]; then
   echo 'is empty'
else
   echo 'contains only digits'
fi
Run Code Online (Sandbox Code Playgroud)

  • 自 4.1 起,“extglob”默认在“[[...]]”内生效,这是“新的”。你仍然需要 `shopt -s extglob` 和 Macos 上的古老 bash。 (2认同)