整えるorder throughは、LC_COLLATE
個々の文字のソート順を定義するだけでなく、文字範囲の意味も定義します。それともそうでしょうか?次のスニペットを検討してください。
unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'
直観的にはB
is not in[a-z]
なので、何も出力しないでください。これがUbuntu 8.04または10.04で発生する現象です。しかし、Debian lenny または squeeze を実行している一部のコンピュータでは、範囲に大文字を含め、照合順序の内側と間B
のa-z
すべてのエントリが含まれることがわかります。a
z
B
Z
テストされたすべてのシステムにen_US
ロケールが作成されました。私もロケールを変更してみました。B
上記のマッチングマシンでは、これは{en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8}
日本語(利用可能なエンコーディング)および/を除いて。C
POSIX
正規表現では、文字の範囲はどういう意味ですか?、いつASCIIを上回るか。一部のDebianインストールと他のDebianインストールとUbuntuの間に違いがあるのはなぜですか?他のシステムはどのように機能しますか?誰が正しい、誰がバグを報告する必要がありますか?
[a-z]
(主にGNU libcベースのシステムでは、ロケールなどの文字範囲の動作について具体的に尋ねることですen_US
。小文字またはASCII小文字を一致させる方法を尋ねることではありません。)
2台のDebianシステムでは、1つがオンになり、1つがオフになると、B
出力[a-z]
は次のLC_COLLATE=en_US locale -k LC_COLLATE
ようになります。
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=1
collate-codeset="ISO-8859-1"
の出力はLC_COLLATE=en_US.utf8 locale -k LC_COLLATE
次のとおりです。
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2039
collate-codeset="UTF-8"
答え1
C
ロケール以外のものを使用する場合、同様の範囲は[a-z]
ロケールによって異なり、常に期待される結果を提供しないため、使用しないでください。すでに発生した大文字と小文字の問題に加えて、一部のロケールでは分音符を使用して文字を処理します。ㅏ)は基本文字(つまり、ㅏ)。
代わりに名前付き文字クラスを使用してください。
echo B | grep '[[:lower:]]'
これにより、そのロケールに対して常に正しい結果が得られます。ただし、入力テキストと適用するテストの意味を反映するロケールを選択する必要があります。
たとえば、特定のバイト値を見つける必要がある場合は、常にC
利用可能なロケールを使用してください。
echo B | LANG=C grep '[a-z]'
これが期待どおりに機能しない場合、これは実際にバグです。
答え2
正規表現の範囲は照合順序設定に従う必要があります。関連規格は次のとおりです。http://pubs.opengroup.org/onlinepubs/007908799/xbd/re.html(「範囲表現」を探してください)。したがって、適切なロケールに従って合理的な定義を出力する必要がecho B | LC_COLLATE=en_US grep '[a-z]'
あります。B
なぜこれがうまくいかないのかを説明することはできませんが、正しくインストールされ構成されている非古代システムでこの問題が発生した場合、非常に驚くでしょう。