次の例を考えてみましょう。
$ bash --version
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ LC_COLLATE=C bash --norc -c '[[ B == [a-z] ]] && echo yes || echo no'
no
$ LC_COLLATE=en_GB bash --norc -c '[[ B == [a-z] ]] && echo yes || echo no'
yes
$ LC_COLLATE=C bash --norc -c '[[ B =~ [a-z] ]] && echo yes || echo no'
no
$ LC_COLLATE=en_GB bash --norc -c '[[ B =~ [a-z] ]] && echo yes || echo no'
no
マッチングするときそういうようだ。模様(つまり、=
orを使用==
) BashはLC_COLLATEに従って対照します。ただし、正規表現と一致する場合(つまり、または使用=~
)、BashはPOSIXまたは同様のものに基づいて対照します。
Zshは-少なくとも-すべての場合にzsh 5.8.0.2-dev (x86_64-pc-linux-gnu)
印刷します。no
[a-z]
パターンや正規表現に使用する場合、それが正確に一致することが保証されますか?
答え1
[a-z]
いいえ、正確に一致する保証はありません。
他のロケールでは可能です"C"
(ユーティリティがPOSIX規格の場合)。
重要な問題は「範囲」表現(使用法-
)にあります。
このような明確なリストは[abcdefghijklmnopqrstuvwxyz]
決して失敗しません。
POSIXは正確に要求しますa-z
。abcdefghijklmnopqrstvwxyz
はい。ただし、ロケールがPOSIXデフォルトの場合にのみ適用されます"C"
。
POSIX仕様では:
POSIXロケールでは、範囲式は、組み合わせシーケンスの2つの要素を含む2つの要素間の組み合わせ要素のセットを表します。範囲式には、他のロケールで指定されていない動作があります。:厳格なコンプライアンスアプリケーションは、スコープ式が有効かどうか、または一致する組み合わせ要素のセットに依存してはいけません。範囲式は、( '-')で区切られた始点と終点として表現する必要があります。
POSIXが特定の意味を要求しても、a-z
すべてのアプリケーションは単にPOSIXを無視することを選択できます。
氷山の一角をお見せしましょう。
Python 2.7はASCIIにのみ一致しますa-z
が、Python 3.0は他の多くのUnicode文字と一致します。 Bash は 3.2 より前の ASCII にのみマッチングするために使用されました。次に、一致させる文字を決定します。整えるa
とは、アプリのロケールに含めることができz
ますA-Y
(通常は含まれていません)。Z
bashバージョン5.0+では、globasciirangesオプションを使用して範囲を設定できます。存在する基本的にa-z
意図を一致させます。最大ASCII文字。
$ LC_COLLATE=en_GB bash -c 'shopt -u globasciiranges; [[ B == [a-z] ]] && echo yes || echo no'
yes
$ LC_COLLATE=en_GB bash -c 'shopt -s globasciiranges; [[ B == [a-z] ]] && echo yes || echo no'
no
ただし、globasciirangesが有効なbash 5.0であっても、== [a-z]
en_GB.utf-8ロケールでは2190文字と一致します。理解を助けるためにa
許可される類似文字のリストは次のとおりです。
a a ͣ ⒜