あなたの試み

あなたの試み

ユーザーにURLを入力するように求めたいのですが、URLには、、、、、、、、、、、、、、、、、のみを含めることがA-Zできます。a-z0-9&./=_-:?

たとえば、次のようになります。

Enter URL:
$ http://youtube.com/watch?v=1234df_AQ-x
That URL is allowed.

Enter URL:
$ https://unix.stackexchange.com/$FAKEurl%

答え1

あなたは近いです。

URL に許可されている文字が 1 つ以上含まれているのではなく、許可されていない文字が 1 つ以上含まれていることを確認し、誤ったものとして報告しようとしています。

!(他のシェル^でも機能しますbash)を使用して、角かっこ式の文字セットを無効にすることができます。

とにかく、、、、などの範囲を使用して文字を明示的に個別にリストするのが正しいですa-z。 (熱い26+26+10文字のみ一致)A-Z0-9Cロケール他のロケールでは、他の何千もの文字と一致することも、複数の文字で構成されたソートされた要素(および間に並べられた要素など)Aと一致させることもできます。ZÉA-Z

case $URL in
  ("" | *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_/\&?:.=-]*)
    echo >&2 "That URL is NOT allowed.";;
  (*)
    echo "That URL is allowed.";;
esac

答え2

あなたの試み

許可された文字が1つ以上含まれているすべてのURLが許可されていると見なされるため、試行が期待どおりに機能しない可能性があります。正式には、URLを次のように組み合わせます。

<anything><allowed_character><anything>

一致するものがない場合は、URL を拒否します。

これが役に立つかもしれません

if ... else ... fi使用する場合

if [[ "${URL}" =~ [^A-Za-z0-9\&./=_:?-] ]]; then
    echo "That URL is NOT allowed."
else
    echo "That URL is allowed."
fi

あなたが望むことをすることもできます。

ここでは、二項演算子を使用して、=~正規表現に[^A-Za-z0-9\&\./=_-:\?]一致する項目を検索します"${URL}"。この演算子は"${URL}"正規表現に一致するために文字列全体を必要とせず、一致する部分文字列が一致します。これらの一致は、URLで許可されていない文字について見つけることができます。 "not" は^文字セット定義の先行カラット ( ) から出ます。!条件式には否定はありません。

禁止文字が含まれている場合、正規"${URL}"表現は一致し、複合コマンドは[[...]]true(0終了状態)と評価されます。

答え3

現在のロジックが間違っています。入力URLのすべての文字が許可された文字セットの外側にある場合にのみtrueを返します。

次のことを試してください

if [[ "${URL}"  = *[!A-Za-z0-9\&./=_:?-]* ]]
then
  echo "That URL is NOT allowed."
else
  echo "That URL is allowed"
fi

文字範囲の否定(!)のため、このチェックは、入力URLに許可されている文字セットを超えた1つ以上の文字が含まれている場合はtrueを返すように設計されています。

答え4

コンパクトなソリューション

コンパクトなソリューションを好む場合は、次のソリューションを使用できます。

[ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ] && echo No || echo Yes

説明する

${<variable>//<pattern>}このソリューションは、より一般的な型の特殊なケースである型の引数拡張を使用します。

${<variable>//<pattern>/<replace>}

シェルはそれを値に拡張し、<variable>その中のすべての項目を<pattern>置き換えます<replace>。私たちの場合は<replace>空ですので、末尾のスラッシュを省略することもできます<pattern>

その結果、"${URL//[A-Za-z0-9\&.\/=_:?-]}"URLは許可されているすべての文字が削除された状態に拡張されます。残余がない場合、つまりURLが[ ... ]実際に許可されている場合は[ ]false(終了ステータス0)が生成されます。残りの文字がある場合、その文字は抑制され、空でない文字列である形式を[ ... ]持ち、結果はtrue(終了ステータス1)です。[ <nes> ]<nes>

&&コマンド全体は、制御演算子(and)と(or)で区切られた3つのコマンドのリストで||、左側に関連付けられています。したがって、サブリストは

[ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ] && echo No

まず評価を受けてください。ここで、&&2番目のオペランドは、最初のオペランドがtrue(0終了状態)と評価された場合にのみ評価されます。これは、URLに禁止文字が含まれている場合に発生します。したがって、echoこの場合、正解 "No" が提供され、このサブリストの終了ステータスは次のechoコマンドから得られます: 0(true)。

逆に、URLが許可されている場合、サブリストの終了ステータスは[ ... ]1(false)から来ます。

これで、リストの残りの部分を作成します。

<sub-list> || echo Yes

||この演算子は、最初のオペランドがfalse(終了ステータスが0と異なる)の場合にのみ最後のコマンドを実行します。したがって、偽の場合のみ<sub-list>、つまり許可されたURLの場合は「はい」を取得します。

構造

もちろん、構造内で上記のコマンドを使用する[ ... ]こともできます。ifほとんどの場合、これにより読みやすいコードが生成されます。

if [ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ]; then
    echo "That URL is NOT allowed."
else
    echo "That URL is allowed."
fi

関連情報