はむはむエンジニアぶろぐ

このブログのコンセプトは"ハッキングの為なら愛する家族を傷つけることをいとわない" 自分にとってエンジニアリングは "手段ではなく生きる目的" である

Perl 正規表現で文字化けしたら解釈系が正しく文字コードを認識できていない

f:id:secret_hamuhamu:20150426020452p:plain
Perlで、正規表現を使って文字を抜き出そうとした所、文字化けしてしまった。
文字列の末尾に <ef> とか <bc> とかがついてしまうのだ。
実はこれ、Perl文字コードを正しく解釈できていないからである。

環境構成

現象

正規表現で以下の対象文字列に対して特定の文字列を抜き出したい。

対象文字列 抜き出したい対象文字列
ほげほげ(11-111) - ふがふが ほげほげ(11-111)
ほげほげ(11-111) - ふがふが ほげほげ(11-111)

1は(が半角。2は(が全角です。
1の場合は問題無いですが、2の場合は問題が発生します。


Perlのコード。

$text = 'ほげほげ(11-111) - ほげほげ';

if ( $text =~ /.*[\((]\d+-\d+[\))]/ ) {
    print $&;
}

# 出力結果
ほげほげ(11-111<ef>

# ]の後ろに.を追加
if ( $text =~ /.*[\((]\d+-\d+[\))]./ ) {
    print $&;
}

# 出力結果
ほげほげ(11-111<ef><bc>

# ]の後ろに..を追加
if ( $text =~ /.*[\((]\d+-\d+[\))]../ ) {
    print $&;
}

# 出力結果
ほげほげ(11-111


解決

Perlが、utf-8と正しく解釈できていないためである。
全角 utf-8文字コードは、efbc89である。
参考 UTF-8 日本語文字一覧

Perlの解釈系(インタプリタ)に、書かれたコードはutf-8だよと教えてあげる必要がある。

use utf8;

最近読んだ本

Perl徹底攻略 (WEB+DB PRESS plus)

Perl徹底攻略 (WEB+DB PRESS plus)

Perlベストプラクティス

Perlベストプラクティス

モダンPerl入門 (CodeZine BOOKS)

モダンPerl入門 (CodeZine BOOKS)

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)