質問: Perlのプログラムにて、あるファイルがプレーンテキストのみで書かれていることを 正規表現で判別したいのですが、どのようにパターンを書けば実現出来るか悩んでいます。 Linuxのfileコマンドでテキスト/バイナリの識別ができますが、 そのようなことを正規表現で書けるものでしょうか。
回答: 直接正規表現を使う必要はありません。 というか、デコードされていないバイト文字列に正規表現を直接ひっかけるのは労多くして功少なしです。 そのかわり、`Encode::Guess`で代用するのはどうでしょうか? プレーンテキストはバイナリの集まりで構成されています。 ですので、本来プレーンテキストとバイナリの間に明確な区別はありません。 プレーンテキストはあくまで人間の目がバイト列をそのように認識しているだけです。 Shift_JISには使用されないバイト列のパターンも存在しますから、 それを**運良く**拾ってこれるなら「Shift_JISではない」と言うことはできます。 もちろんLinuxのfileコマンドも例外ではありません。 > > perlfaq6 - マルチバイト文字を含む文字列をマッチングさせるには? > > > > > プレーンテキストかバイナリかを機械的に見分けるには、結局統計判断に頼ることになります。 もしプレーンテキストというのがasciiまたはutf8だけを指しているのであれば、ファイルを`open`するまでもなく`-T`ファイルテストを利用できます。 ``` $ perl -E 'say "TEXT" if -T "utf8.txt";' ``` > > -T ファイルは ASCII または UTF-8 テキストファイル (発見的に推測します)。 > > > > > 標準入力に`find(1)`や`ls(1)`を使いたい場合はこんな感じでもOKです。 ``` $ ls | perl -nlE 'say $_ if -T;' ``` Shift_JISも含めるとなると、いよいよファイルを`open`する必要があります。 事前にプレーンテキストの条件として`Shift_JIS`でいいのか再度確認して下さい。 歴史的な経緯もあって、一般には`Shift_JIS`と呼ばれていても実際は`Windows-31j (cp932)`を指している場合があります。`(株)`や`III`を文字とみなし、かつIBM拡張文字等も気にしなくて良いのであれば、`cp932`で見るのが良さそうです。 ``` $ ls | perl -MEncode::Guess -nlE 'open $fh, "<", $_; say $_ if ref guess_encoding(do { local $/; <$fh> }, qw/utf8 cp932/);' ```