グローバルパターンと数値の一致

グローバルパターンと数値の一致

一致のためにグローバルパターンを使用しようとしています。しかし、このゲームは失敗します:

dgt='^+([0123456789])$'
[[ "$1" == $dgt  ]] && echo "SUCCESS" || echo "FAILURE"

答え1

パターンは、^+([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

拡張されたワイルドカードパターンを持たないシェルでは、数値以外の項目を一致させる方が簡単です。

#!/bin/sh

case $1 in
    *[!0123456789]*)
        echo 'contains non-digit' ;;
    '')
        echo 'is empty' ;;
    *)
        echo 'contains only digits'
esac

シェルでは、bash上記のコードは移植可能で互換性のあるshすべてのシェルで動作するため、使用することもできます。

#!/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

答え2

グローバルパターンマッチングが必ずしも必要でない場合は、正規表現を使用することもできます。

=~Bashでは正規表現演算子を使用できます。

dgt='^[[:digit:]]+$'
[[ "$1" =~ $dgt ]] && echo "SUCCESS" || echo "FAILURE"

関連情報