bashを使用した正規表現角括弧式

bashを使用した正規表現角括弧式

英数字、下線、ピリオド、ダッシュ、プラス記号を含むユーザー入力のみを許可する正規表現を作成したいと思います。

Bashスクリプトには次のものがあります。

VALID="^[0-9a-zA-Z_\.\-\+]+$"
THE_INPUT=$1
if [[ ! $THE_INPUT =~ $VALID ]]; then
    echo "ERROR"
    exit 1  
fi

ユーザーが - を使用して入力したときにこれが機能しないのはなぜですか?

ユーザー入力の例:

  1. 素晴らしい食べ物.png

    私。エラー発生

  2. いいね_+食べ物.png

    私。エラーは発生しません。

答え1

[0-9a-zA-Z_\.\-\+]POSIX 基本または拡張正規表現の角かっこ式の一致:

  • 0-90:との間の範囲の照合要素(単一文字である必要はありません!)9(ロケールによっては何でも構いません。CPOSIX
  • a-zA-ZatozとtoとA同じですZ
  • _\.:下線、バックスラッシュまたはピリオド:
  • \-\\:との間に配置された要素を照合します\。たぶんそうかも\しれませんが、あなたは決して知りません。
  • \+:もう一度バックスラッシュを入力してください+

\角かっこ式では特別ではありません。

setにリテラルを含めるには、リテラルを最後または最初(または負のセットでは直後)に-配置する必要があります。^

bash は POSIX 拡張正規表現を=~演算子として使用します。

希望する場所は次のとおりです。

VALID='^[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.+-]+$'

に切り替えるオプションがある場合は、zsh拡張glob演算子を使用できます。これは、さまざまな構文とあまり驚くべき動作を持つ拡張正規表現の親セットであり、正規表現とは異なり、テキストではなく項目を処理できます。

set -o extendedglob
VALID='[0-9a-zA-Z_+.-]##'

if [[ $input != $~VALID ]]; then...

(ここの~内容は$VALID文字通りの意味ではなくパターンとみなされます。)

また、ロケールに分類されているすべての文字との文字に一致する[:WORD:]文字クラスもあります。alnum$WORDCHARS

C言語環境では、以下を定義してWORDCHARS='.-+_'使用できます。

set -o extendedglob # needed for ##, the equivalent of ERE +.
VALID='[[:WORD:]]##'

zshPCREもサポートされ、PCREには角括弧式もあります。

zmodload zsh/pcre
VALID='^[0-9a-zA-Z._+-]+\z'

if [[ ! $input -pcre-match $VALID ]]; then...

または、=~EREの代わりにPCREを使用してください。

set -o rematchpcre
VALID='^[0-9a-zA-Z._+-]+\z'

if [[ ! $input =~ $VALID ]]; then...

そこでもVALID='^[0-9a-zA-Z\-._+]+\z'使えます。

PCREはUTF-8以外のマルチバイト文字セットをサポートしておらず、$inputUTF-8が無効な場合、上記はUTF-8ロケールでエラーを報告します。

Cロケールでは、sと下線に一致するものVALID='^[\w.+-]\z'を使用することもできます。\walnum


¹ awk は拡張正規表現を使用する点で例外ですが、角かっこ式\では依然として特別です。少なくとも一部の実装では

答え2

通常、正規表現では、-文字クラスブロック内の文字は範囲を意味します[a-z]いいえ範囲を暗示するのは、文字クラス記述子の最後にハイフンを置くことです。あなたのスクリプトでこれを行うと、好きなように動作するようです。

VALID="^[0-9a-zA-Z_\.\+\-]+$"

したがって:

$ ./741634.sh parameter/with/slashes
ERROR
$ ./741634.sh parameter-with-dashes
$

関連情報