はじめに
POSIX で標準化されている正規表現の 照合シンボル [.string.]、等価クラス [=char=]、文字クラス [:classname:] の正しい意味と使い方です。検証は Debian 上で行っています。シェルスクリプト(コマンド)で動作確認していますが、本質的にはロケールの話なので各プログラミング言語にも当てはまるのではないかと思います。
注意
これらはすべて [] の中で使います。念の為ですがブラケットが 2 重になっているわけではありません。[] の中に[:digit:] 等を書いているだけです。だから [a[:digit:]z] のように書くこともできます。ただし商用 Unix (Solaris 10/11 等)では互換性のために POSIX に準拠してない歴史的なコマンドがデフォルトになっている場合があり、[] の中に [:alnum:] を入れると動かなかったりするので、POSIX 準拠モードにしてから使用してください。(参考 「え?UNIXなのにPOSIXに準拠してないの!?」シェルスクリプト実行環境をPOSIX準拠モードに変更して互換性を上げる方法 (Solaris, AIX, HP-UX, Linux, macOS, BSD))
POSIX に準拠している環境であれば動かないことはないと思いますが、もしこの記事に書いた通りにやっても動かない環境があれば教えて下さい。(繰り返しますが、商用 Unix では POSIX 準拠モードにするのを忘れないこと)
照合シンボル [.string.]
一部の言語(ロケール)には、アルファベット 2 文字で 1 文字を意味する「二重音字」というのがあるようで、それにマッチさせるためのものです。
参考
https://stackoverflow.com/questions/35042202/regex-collating-symbols
ウェールズ語の正書法
$ echo "a cch chc z" | LC_COLLATE=cy_GB.utf8 sed 's/[a[.ch.]z]/@/g'
@ c@ @c @
実行して「無効な照合文字です」とか「Invalid collation character」とか「invalid collating element」とかいうエラーが出る場合は、適切なロケールに設定されていないからです。locale -a で指定したロケールがインストールされていることを確認してください。なお Debian でロケールの追加は dpkg-reconfigure locales を使います。
等価クラス [=char=]
アクセント記号がついていてもついてなくてもマッチします。
$ echo 1e2è3é4ê5ë6 | LC_COLLATE=en_US.UTF-8 sed 's/[a[=e=]z]/@/g'
1@2@3@4@5@6
正しくマッチしないのは適切なロケールに設定されていないからです。locale -a で指定したロケールがインストールされていることを確認してください。
文字クラス [:classname:]
POSIX 文字(キャラクタ)クラスとマッチします。
$ echo "abc123def" | sed "s/[a[:digit:]z]/@/g"
@bc@@@def
以下の文字クラス名はすべてのロケールで使用可能です。
[:alnum:], [:cntrl:], [:lower:], [:space:], [:alpha:], [:digit:], [:print:], [:upper:], [:blank:], [:graph:], [:punct:], [:xdigit:]
追加で [:name:] でロケール固有の文字クラスが使えそうなんですが sed でも grep でも使えませんでした。
POSIX - Regular Expressions より
In addition, character class expressions of the form:
[:name:]
are recognized in those locales where the name keyword has been given a charclass definition in the LC_CTYPE category.
以下は長い行を折り返しています。
$ locale -k LC_CTYPE | grep ctype-class-names
ctype-class-names="upper";"lower";"alpha";"digit";"xdigit";"space";"print";
"graph";"blank";"cntrl";"punct";"alnum";"combining";"combining_level3";
"jspace";"jhira";"jkata";"jkanji";"jdigit"
/usr/share/i18n/locales/ja_JP にも書いてあるので [:jhira:] とか使えそうなんですが。
↧