文字列がどのようなもので始まるのか、それとも何を含むのかを調べる関数を書いてください。

文字列がどのようなもので始まるのか、それとも何を含むのかを調べる関数を書いてください。

var与えられた変数(例えば)が与えられた文字列のリスト内の単語で始まるかどうかを確認する関数を書きたいです。このリストは変更されません。

インスタンス化するために、またはvarで始まるかどうかを確認したいとしますaaabc3@3

varまた、文字が含まれていることを確認したいと思います>

この関数が呼び出されると仮定すると、check_func私の意図された用途は次のとおりです。

if check_func "$var"; then
    do stuff
fi

aardvarkたとえば、とのために「何かを行う」必要がありますabcdef[email protected]12>5


私は見たこの問題ユーザーが作品の一部を提供する状況:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }

上記のリストを繰り返し、この機能を使用するという考えです。私の難しさは、シャットダウン(または復帰に代わるもの)がこれをどのように行うべきかを正確に理解していないことです。

答え1

check_prefixes () {
    value=$1

    for prefix in aa abc 3@3; do
        case $value in
            "$prefix"*) return 0
        esac
    done

    return 1
}

check_contains_gt () {
    value=$1

    case $value in
        *">"*) return 0
    esac

    return 1
}

var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
    printf '"%s" contains ">" and starts with one of the prefixes\n' "$var"
fi

テストを2つの機能に分けました。case ... esacこれが決定されると、両方が使用され、成功(0)を返します。一致するものがない場合は、 failure(1) が返されます。

プレフィックスリストを動的リストのようにするには、最初の関数を次のように書くことができます。

check_prefixes () {
    value=$1
    shift

    for prefix do
        case $value in
            "$prefix"*) return 0
        esac
    done

    return 1
}

(確認する値は最初のパラメータです。これを関数のパラメータリストに保存し、関数のパラメータリストから削除します。残りのパラメータを繰り返します。)次に、valueshiftのように呼び出します。

check_prefixes "$var" aa abc 3@3

2番目の機能も同様の方法で変更できます。

check_contains () {
    value=$1
    shift

    case $value in
        *"$1"*) return 0
    esac

    return 1
}

(任意の部分文字列を確認してください)または

check_contains_oneof () {
    value=$1
    shift

    for substring do
        case $value in
            *"$substring"*) return 0
        esac
    done

    return 1
}

(複数のサブストリングのいずれかを確認してください)

答え2

バッシュの場合:

正規表現のプロパティを使用すると、何もstart含めたり含めたりせずに^作成できますcontain

確認する正規表現のリストスタートそしてaa abcまたは3@3そして含む >例:

^aa ^abc ^3@3 >

それを作る適切にリストを引用してbashに正規表現(=~)を使用するように依頼してください。

check_func() {
               matched=1
               for test_regex in '^aa' '^abc' '^3@3' '>'; do
                   if [[ $var =~ $test_regex ]] ; then
                       matched=0
                       break 
                   fi
               done
               return "$matched"
              }

var='aaIsAMatch'
if check_func; then
    echo "A match was found"
fi

関数にはマッチリストと変数名がハードコーディングされています。

配列変数の正規表現のリストと、最初の引数をテストする値が提供されます。

check_func() {
               local matched; matched=1
               for t in "${test_regex[@]}"; do
                   [[ $1 =~ $t ]] && { matched=0; break; } 
               done
               return "$matched"
              }


test_regex=('^aa' '^abc' '^3@3' '>')

if check_func 'aaIsAMatch'; then
    echo "A match was found"
fi

この関数は、変数名(値の代わりに)を最初の引数として使用するようにさらに拡張できます。

POSIX

posixシェルには正規表現がなく、テストできる唯一の方法はCaseステートメントであるため、Caseステートメントを使用する必要があります。残念ながら、以前のシェル([拡張globは利用できません] [1])では、すべてのテストを繰り返す必要があります。そしてglobは次のようになります。

'aa*' 'abc*' '3@3*' '*>*'

複数のglobに対して複数の入力文字列をテストするスクリプト例:

check_func() { :
           matched=1
       value=$1; shift
           for t in "$@"; do
               case $value in $t) matched=0; #break;; esac
                  echo "matched $value with $t"
                  ;;
       esac
       done
           return "$matched"
         }


for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
        echo "========A match was found for \"$var\""
fi
done

この関数の単純なバージョンは、正確に必要なタスクを実行します。

check_func() { :
               matched=1
               value=$1; shift
                   for t in "$@"; do
                       case $value in $t) matched=0; break;; esac
                   done
               return "$matched"
             }

答え3

このステートメントの役割は、case2番目のパラメータを関数($2)に渡すことです。パターンと一致する場合"$1"*、つまり関数の最初のパラメータの後に何もない場合、trueステートメントは実行され終了しますcasetrue何も実行せずに状態0を返します。それ以外の場合、一致するもの、*つまり何もない場合は、falseステートメントが実行され終了しますcasefalse何もしないで状態 1 を返します。したがって、case2番目のパラメーターが最初のパラメーターで始まる場合、ステートメントの状況は0、そうでない場合は1です。これは関数の最後の(そして唯一の)ステートメントなので、関数は2番目の引数が最初の引数で始まる場合は0を返し、そうでない場合は1を返します。

条件文(ifシェルの条件文など)が0を返す場合、その文はtrueと見なされ、そうでない場合はfalseと見なされます。したがって、値が次から始まる場合は、それ以外の場合は印刷してくださいif beginswith "$var" "string"; then echo yes; else echo no; fiyesvarstringno

この関数を書く方法はいくつかあります。たとえば、作成者は関数の最後のステートメントなので、andの代わりにreturn 0orを使用できます。関数は、関数パラメータ(および)への参照を使用したい文字列に変更して、関数にラップすることなく関数本体を直接使用できるように作成されました。return 1truefalse$1$2

複数のプレフィックスを許可するには、ループで繰り返します。一致するプレフィックスが見つかると、true(0)状態の関数から返されます。一致するプレフィックスがない場合は、エラー状態(通常は1)が返されます。

# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with () {
  string=$1
  shift
  for prefix in "$@"; do
    case "$string" in
      "$prefix"*) return 0;;
    esac
  done
  return 1
}

if begins_with "$var" 'aa' 'abc' '3@3'; then
  echo "The value starts with one of the permitted prefixes"
fi

サフィックスをテストするには、代わり*"$suffix"にパターンを"$prefix"*使用します。部分文字列をテストするには、*"$substring"*ここで二重引用符を使用する必要があります。それ以外の場合、変数はパターンとして解釈されます。たとえば、

suffix='?'
case "$var" in
  *"$suffix") echo "The value of var ends with a question mark";; 
esac
case "$var" in
  *$suffix) echo "The value of var is not empty";; 
esac

答え4

質問の説明に従って修正されました。 これはあまりエレガントであまり柔軟ではありませんが、他の答えよりもコンパクトです。

check_func() {
        case "$1" in
            ( aa* | abc* | 3@3*  | *">"*)
                return 0
        esac
        return 1
}

aardvarkこれは、およびabcdefに対してtrueを返します。もちろん、、があります。[email protected]12>5aard>varkabc<def>ghi3@3>3

関連情報