燈明日記 このページをアンテナに追加 RSSフィード

ごあいさつ

燈明日記へようこそ!!

燈明日記の主なテーマは、以下の通りです。

そして、燈明日記へ来られたのも『私』と『あなた』の何かのご縁です。なので、どうぞごゆっくりご覧下さい!

2008/8/2(土)

[] シフトJIS漢字のファイル名にマッチしてみる

Perlベストプラクティス

たとえば、./hoge配下に『テストソース.txt』というファイルがあったとします。

検索文字列『ソース』で、./hoge配下を検索して、このファイルにマッチさせるには、以下の感じです。


◆その1:コードはshiftjis、処理はshiftjis、標準入出力はshiftjis

#!/usr/bin/perl
use strict;
use warnings;

while (my $fileName = glob("./hoge/*")) {
    if ($fileName =~ /ソース/) {
        print "Match\n";
    }
    else {
        print "Unmatch\n";
    }
    print $fileName, "\n";
}

実行結果

C:\test>perl kanji00.pl
Unmatched [ in regex; marked by <-- HERE in m/メ[ <-- HERE ス/ at kanji00.pl line 6.

しかし、上記ではマッチしません。

というか、正規表現エラーになります。

これは、『ソース』の『ー』の第2バイトが『[』のコードになっているからです。

そして、閉じの『]』がないために正規表現エラーになるのです。

なので、『[』を普通の文字扱いするために、『ソース』を\Qと\Eで囲んでみます。


◆その2:コードはshiftjis、処理はshiftjis、標準入出力はshiftjis

#!/usr/bin/perl
use strict;
use warnings;

while (my $fileName = glob("./hoge/*")) {
    if ($fileName =~ /\Qソース\E/) {
        print "Match\n";
    }
    else {
        print "Unmatch\n";
    }
    print $fileName, "\n";
}

実行結果

C:\test>perl kanji01.pl
Unmatch
./hoge/テストソース.txt

しかし、上記ではマッチしません。

なぜかというと、 /\Qソース\E/は、\Qより先に『ソース』文字列が評価されるので、基本的に『[』をエスケープしたに過ぎません。

なので、一度『ソース』文字列を変数に格納してみます。


◆その3:コードはshiftjis、処理はshiftjis、標準入出力はshiftjis

#!/usr/bin/perl
use strict;
use warnings;

while (my $fileName = glob("./hoge/*")) {
    my $wk = "ソース";
    if ($fileName =~ /\Q$wk\E/) {
        print "Match\n";
    }
    else {
        print "Unmatch\n";
    }
    print $fileName, "\n";
}

実行結果

C:\test>perl kanji02x.pl
Unmatch
./hoge/テストソース.txt

しかし、上記ではマッチしません。

これは、『my $wk = "ソース";』で『ソ』の第2バイトがエスケープ文字『\』のコードになっているからです。

そして、『ソ』の第1バイトと『ー』の第1バイトがくっ付いてしまうのです。たぶん。

なので、変数展開しないようにシングルクォート『my $wk = 'ソース';』にしてみます。


◆その4:コードはshiftjis、処理はshiftjis、標準入出力はshiftjis

#!/usr/bin/perl
use strict;
use warnings;

while (my $fileName = glob("./hoge/*")) {
    my $wk = 'ソース';
    if ($fileName =~ /\Q$wk\E/) {
        print "Match\n";
    }
    else {
        print "Unmatch\n";
    }
    print $fileName, "\n";
}

実行結果

C:\test>perl kanji02.pl
Match
./hoge/テストソース.txt

今度は、上手く行きました。

ということで、シフトJIS漢字を扱うには大変なわけです。

なので、処理はUTF-8にして、コードと標準入出力をshiftjisにしてみます。


◆その5:コードはshiftjis、処理はUTF-8、標準入出力はshiftjis

#!/usr/bin/perl
use strict;
use warnings;
use Encode;

# 標準入出力をutf-8からshiftjisへエンコーディングする
use encoding 'shiftjis';

while (my $fileName = glob("./hoge/*")) {

    # $fileNameをshiftjisからutf-8へデコード
    $fileName = decode('shiftjis', $fileName);

    if ($fileName =~ /ソース/) {
        print "Match\n";
    }
    else {
        print "Unmatch\n";
    }
    print $fileName, "\n";
}

実行結果

C:\test>perl kanji03.pl
Match
./hoge/テストソース.txt

今度も、上手く行きました。

しかし、WINDOWSでの漢字処理は、コードも処理もUTF-8にして、標準入出力をshiftjisが推奨らしい。

なので、スクリプトコードをUTF-8にして・・・。


◆その6:コードはUTF-8、処理はUTF-8、標準入出力はshiftjis

#!/usr/bin/perl
use strict;
use warnings;
use Encode;

# スクリプトの文字コードがutf-8であることの明示
use utf8;

# 標準出力をshiftjisでエンコーディング
binmode STDOUT, ':encoding(shiftjis)'; 

while (my $fileName = glob("./hoge/*")) {

    # $fileNameをshiftjisからutf-8へデコード
    $fileName = decode('shiftjis', $fileName);
    if ($fileName =~ /ソース/) {
        print "Match\n";
    }
    else {
        print "Unmatch\n";
    }
    print $fileName, "\n";
}

実行結果

C:\test>perl kanji04.pl
Match
./hoge/テストソース.txt

そう、これが正解みたいですね・・・。


詳説 正規表現 第3版

詳説 正規表現 第3版

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/chaichanPaPa/20080802/1217660826
リンク元