created: 2023-09-20T03:28:59.652Z
perlのワンライナーでつけるコマンドライン引数 -C -Mutf8
perl はデフォルトでは文字列を latin1 としてパースするが、UTF-8 として扱ってほしい場合に使うコマンドラインオプションは 2 つある。
-C
-C
をつけると、標準入力と出力(エラーも)が UTF-8 だよ、という指示になる。標準入力に渡すデータにマルチバイト文字が含まれていて、そのバイト列をきちんとした文字として扱ってほしい場合はつける必要がある。
-C
にはさらにオプションがつけられるが単体でも動く。単体で指定するとハマらなさそうな指定になる。
-C が単体で(数値やオプションリストなし)起動されるか、 "PERL_UNICODE" 環境変数が空文字列 "" の場合、-CSDL と 同じ効果となります。
-Mutf8
-Mutf8
はモジュールオプションである -M
の引数に utf8
を指示したもの。こちらは標準入出力ではなく、perl のソースコードを UTF-8 と認識してもらうためのもの。
確認
マルチバイト文字が入っている標準入力をつかって動作を確認する。
$ echo "あいうえお"
あいうえお
まずはオプションを両方つけて STDIN とソースコードが両方とも UTF-8 として扱われる場合。
$ echo "あいうえお" | perl -C -Mutf8 -nlE '/あ/ and say'
あいうえお # 期待通り
つぎに、片方だけオプションをつける場合。これも期待通りの動作になる。
$ echo "あいうえお" | perl -C -nlE '/あ/ and say'
$ echo "あいうえお" | perl -Mutf8 -nlE '/あ/ and say'
latin1 で表現された あ
と UTF-8 で表現された あ
は、見た目は同じだけどバイト列としては異なるものなので検索には引っかからない。
これを踏まえると、オプションを両方つけない場合に、検索がひっかかる動作は納得しやすい。
$ echo "あいうえお" | perl -nlE '/あ/ and say'
あいうえお
latin1 で表現された あ
で latin1 で表現された あ
を検索しているので、「おなじもの(バイト列)が見つかった」という状態になる。なので検索にはひっかかる。
ユニコードリテラル
あ
を perl ではユニコードリテラルの \x{3042}
として表現することもできる。これは utf8 フラグがついていてもいなくても latin1 としては解釈されず、あ
として解釈される。
$ echo "あいうえお" | perl -C -nlE '/\x{3042}/ and say'
あいうえお
$ echo "あいうえお" | perl -nlE '/\x{3042}/ and say'
前者は -C
オプションで入力を UTF-8 として解釈してもらってるので あ
と \x{3042}
が同じものを指していることになるので検索にひっかかるが、後者は -C
オプションをつけてないので あいうえお
は latin1 として扱われてしまい、\x{3042}
にはマッチしない。