メメメモモ

プログラミング、筋トレ、ゲーム、etc

正規表現マッチがエラーになる時

以下の場合、正規表現エラーになります。

use strict;
use warnings;
use utf8;
use Encode;


my $text = 'test)testetsttest';

my $match = 'test)';

$text =~ s/$match/aaaa/g;

$matchの中にある")"が、正規表現の特殊記号として評価されてしまうのでエラーになります。
$matchの中にある文字列を普通の文字列として扱いたい場合は、
quotemeta関数を使います。

use strict;
use warnings;
use utf8;
use Encode;


my $text = 'test)testetsttest';

my $match = quotemeta('test)');

$text =~ s/$match/aaaa/g;


以下のように一見、正規表現の記号が入っていなくてもエラーになります。

use strict;
use warnings;
use utf8;
use Encode;

my $text = 'hogehoge';
my $match = encode('sjis', 'ニュース');

$text =~ s/$match/news/g;


# 結果
Unmatched [ in regex; marked by <-- HERE in m/?j???[ <-- HERE ?X/ at test2.pl line 10.


これはShift_JISの”ー”の中に"["と同じ文字コードが含まれているからです。
以下は、検証コード。

use strict;
use warnings;
use utf8;
use Encode;


my $sjis = encode('sjis', 'ー');
my $ascii = '[';

warn unpack("H*", $sjis);     # -> 815b                                                                                            
warn unpack("H*", $ascii);    # -> 5b


この場合もquotemeta関数を使えばエラーはなくなります。

use strict;
use warnings;
use utf8;
use Encode;


my $text = encode('sjis', '最新ニュース');
my $match = encode('sjis', 'ニュース');
$match = quotemeta($match);

if ($text =~ /$match/) {
    warn "match";
}