[解決済み] Bashのif文での正規表現マッチング
質問
何がいけなかったのでしょうか?
スペース、小文字、大文字、数字を含むすべての文字列にマッチしようとしました。特殊文字もいいですが、特定の文字をエスケープする必要があると思います。
TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#"
if [[ "$TEST" =~ [^a-zA-Z0-9\ ] ]]; then BLAH; fi
これは明らかに、大文字、小文字、数字、スペースをテストするだけです。しかし、うまくいきません。
* UPDATE *
もっと具体的に説明するべきだったようです。以下は、実際の実際のコード行です。
if [[ "$TITLE" =~ [^a-zA-Z0-9\ ] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; fi
* UPDATE *
./anm.sh: line 265: syntax error in conditional expression
./anm.sh: line 265: syntax error near `&*#]'
./anm.sh: line 265: ` if [[ ! "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; return; fi'
どのように解決するのですか?
bashの
[[ ]]
の構築について知っておくべき重要なことがいくつかあります。一つ目は
の間の単語に対して単語分割とパス名展開が行われません。
[[
と]]
;チルダ展開、パラメータ展開、変数展開、算術展開、コマンド置換、プロセス置換、引用符除去が行われます。
2つ目のことです。
<ブロッククオート追加の二項演算子 '=~' が利用できます。... 演算子の右側の文字列は拡張正規表現とみなされ、それに応じてマッチングされます... パターンのどの部分でも、文字列としてマッチさせるために引用することができます。 .
結果的に
$v
の両側で
=~
はその変数の値に展開されますが、その結果は単語分割やパス名展開されません。言い換えれば、左側で変数の展開を引用しないままにしても全く問題ありませんが、右側で変数の展開が起こることを知っておく必要があります。
というわけで、もしあなたが書いたら
[[ $x =~ [$0-9a-zA-Z] ]]
と書くと
$0
の内部は正規表現が解釈される前に展開されてしまうので、おそらく正規表現のコンパイルに失敗します。
$0
の展開が数字やAscii値が1桁未満の区切り記号で終わっていない限り)。
のように右辺を引用する場合は、次のようになります。
[[ $x =~ "[$0-9a-zA-Z]" ]]
のように引用すると、右辺は正規表現ではなく、普通の文字列として扱われます。
(そして
$0
はまだ展開されます)。この場合、本当に必要なのは
[[ $x =~ [\$0-9a-zA-Z] ]]
の間の表現も同様に
[[
と
]]
は正規表現が解釈される前に単語に分割されます。そのため、正規表現中のスペースはエスケープするか引用符で囲む必要があります。もし文字、数字、スペースにマッチさせたいなら、次のようにします。
[[ $x =~ [0-9a-zA-Z\ ] ]]
. その他の文字も同様に、次のようにエスケープする必要があります。
#
のようにエスケープする必要がある。もちろん、パターンを変数に入れることもできます。
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
bash のレキサを通過するためにエスケープや引用が必要な文字を多く含む正規表現では、多くの人がこのスタイルを好みます。しかし、注意: この場合 はできません。 という変数展開の引用ができません。
# This doesn't work:
if [[ $x =~ "$pat" ]]; then ...
最後に、あなたがやろうとしていることは、変数が有効な文字だけを含んでいるかどうかを確認することだと思います。このチェックを行う最も簡単な方法は、無効な文字が含まれていないことを確認することです。つまり、次のような式です。
valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list
if [[ ! $x =~ [^$valid] ]]; then ...
!
は、テストを否定して "一致しない" 演算子に変え、さらに
[^...]
以外の任意の文字を意味します。
...
を意味します。
パラメータ展開と正規表現演算子の組み合わせにより、bashの正規表現構文は"ほとんど読みやすい"になりますが、まだいくつかのゴチャゴチャがあります。(いつもそうでしょうか?)ひとつは、あなたが
]
を
$valid
であっても
$valid
が引用されていたとしても、一番最初を除いては、です。(これはPosixの正規表現のルールです。
]
を文字クラスに含めたい場合は、先頭に書く必要があります。
-
は最初にも最後にも書くことができるので、もし両方の
]
と
-
で始まる必要があります。
]
で終わり、さらに
-
となり、正規表現 "I know what I'm doing" の顔文字が表示されるようになります。
[][-]
)
関連
-
[解決済み] Scalaで正規表現を使ったパターンマッチを行うには?
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] Bash prints リテラルの改行をエコーする \n
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み】Bashでファイル名と拡張子を抽出する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 最初のマッチで停止する正規表現
-
[解決済み] Atomで改行文字を置き換えるには?
-
[解決済み] bashスクリプトで「cd `echo $0 | sed 's/(.***)\/.*/**1/'` 」はどうするのですか?
-
[解決済み] Apache LocationMatch Regex
-
[解決済み] スペースとタブの任意のシーケンスにマッチする正規表現を作成する方法
-
[解決済み] 文字列の完全一致のための正規表現
-
[解決済み] 一致した正規表現パターンを awk で表示するには?
-
[解決済み] 正規表現、空白文字とコロンを除くすべての非英数字文字
-
[解決済み] 正規表現ネガティブルックアヘッド
-
[解決済み】bashで変数の一文字目を大文字にする。