稲沢市よりお届けしてます。

Perlをはじめとしたプログラミング周りのあれこれについて。Perl、最近書いてないなぁ。

Perlでエスケープシーケンスした16進数の置き換えにハマったけど、quotemeta()で解決した件。

難読化されてるPerlスクリプトを読みたくて、置き換え処理をチョコチョコっと書いたけどうまく動かず。perl -d hoge.pl みたいな感じでデバッガ使って動作確認しても、一見おかしなところは無いっぽかった。

 

原因は、置き換えに使ってる変数に入ってるバックスラッシュだったみたい。

 

うまくいったコードはコチラ

 ↓ ↓ ↓

use strict;
use warnings;

my %hex_ascii = (
	'\x21' => '!' ,
	'\x22' => '"' ,
	'\x23' => '#' ,
	'\x24' => '$' ,
	'\x25' => '%' ,
	'\x26' => '&' ,
	'\x27' => "'" ,
	'\x28' => '(' ,
	'\x29' => ')' ,
	'\x2a' => '*' ,
	'\x2b' => '+' ,
	'\x2c' => ',' ,
	'\x2d' => '-' ,
	'\x2e' => '.' ,
	'\x2f' => '/' ,
	'\x30' => '0' ,
	'\x31' => '1' ,
	'\x32' => '2' ,
	'\x33' => '3' ,
	'\x34' => '4' ,
	'\x35' => '5' ,
	'\x36' => '6' ,
	'\x37' => '7' ,
	'\x38' => '8' ,
	'\x39' => '9' ,
	'\x3a' => ':' ,
	'\x3b' => ';' ,
	'\x3c' => '<' ,
	'\x3d' => '=' ,
	'\x3e' => '>' ,
	'\x3f' => '?' ,
	'\x40' => '@' ,
	'\x41' => 'A' ,
	'\x42' => 'B' ,
	'\x43' => 'C' ,
	'\x44' => 'D' ,
	'\x45' => 'E' ,
	'\x46' => 'F' ,
	'\x47' => 'G' ,
	'\x48' => 'H' ,
	'\x49' => 'I' ,
	'\x4a' => 'J' ,
	'\x4b' => 'K' ,
	'\x4c' => 'L' ,
	'\x4d' => 'M' ,
	'\x4e' => 'N' ,
	'\x4f' => 'O' ,
	'\x50' => 'P' ,
	'\x51' => 'Q' ,
	'\x52' => 'R' ,
	'\x53' => 'S' ,
	'\x54' => 'T' ,
	'\x55' => 'U' ,
	'\x56' => 'V' ,
	'\x57' => 'W' ,
	'\x58' => 'X' ,
	'\x59' => 'Y' ,
	'\x5a' => 'Z' ,
	'\x5b' => '[' ,
	'\x5c' => '\\' ,
	'\x5d' => ']' ,
	'\x5e' => '^' ,
	'\x5f' => '_' ,
	'\x60' => '`' ,
	'\x61' => 'a' ,
	'\x62' => 'b' ,
	'\x63' => 'c' ,
	'\x64' => 'd' ,
	'\x65' => 'e' ,
	'\x66' => 'f' ,
	'\x67' => 'g' ,
	'\x68' => 'h' ,
	'\x69' => 'i' ,
	'\x6a' => 'j' ,
	'\x6b' => 'k' ,
	'\x6c' => 'l' ,
	'\x6d' => 'm' ,
	'\x6e' => 'n' ,
	'\x6f' => 'o' ,
	'\x70' => 'p' ,
	'\x71' => 'q' ,
	'\x72' => 'r' ,
	'\x73' => 's' ,
	'\x74' => 't' ,
	'\x75' => 'u' ,
	'\x76' => 'v' ,
	'\x77' => 'w' ,
	'\x78' => 'x' ,
	'\x79' => 'y' ,
	'\x7a' => 'z' ,
	'\x7b' => '{' ,
	'\x7c' => '|' ,
	'\x7d' => '}' ,
	'\x7e' => '~' ,
);

my @pattern;
while (my $key = each %hex_ascii) {
	push(@pattern, $key);
}

while(my $line = <DATA>) {
	foreach my $key (@pattern) {
		my $meta_key = quotemeta($key);
		$line =~ s/$meta_key/$hex_ascii{"$key"}/g;
	}
	print $line;
}

__DATA__
"\x70\x6f\x6b\x65\x6d\x6f\x6e" =>  "\x47\x4f",


ハッシュのキーをいちいち配列@patternに突っ込まずに、ダイレクトに

while(my $line = <DATA>) {
	while (my ($key, $value) = each %hex_ascii) {
		my $meta_key = quotemeta($key);
		$line =~ s/$meta_key/$value/g;
	}
	print $line;
}

って書く方がスマートですな。



f:id:perl48:20160803173544p:plain


ちゃんと「"pokemon" => "GO"」って出力されてますね。






↓ ↓参考にさせていただいたブログ

文字列を全置換するには (replace) | hydroculのメモ


d.hatena.ne.jp