• ベストアンサー

ShiftJIS 2バイト文字のエスケープ

ShiftJISのファイルを読み込み、2バイト文字の2バイト目が\x5Cの文字でエスケープされてない(\がついていない)文字にたいして\を付加したいのですが、なかなかうまくいきません。 どなたかいい方法をご存知ないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • moon_piyo
  • ベストアンサー率60% (88/146)
回答No.1

こんにちは s/((?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])*?[\x81-\x9F\xE0-\xFC]\x5C)/$1\x5C/g; でどうでしょうか

k17s
質問者

お礼

回答ありがとうございます。 自分も回答されたような置換をためしてはみたのですが、読み込んだファイルがShiftJISでダメ文字がエスケープされていなかった場合は、ダメ文字が2バイト文字と認識されず正規表現にはマッチしないようです。

k17s
質問者

補足

すみません。 ファイルを読み込む際にbinmodeにしたらいけました。 ただしこの方法だと既にエスケープされてる文字に対して更に\x5Cをつけてしまいます。 既にエスケープされているかどうかを判断した上で置換する。 OR 置換した後、ShiftJISで2バイト目が\x5Cの文字のあとに1個以上\x5Cが続くものは\x5Cに置換 等するにはどうすればいいでしょうか?

その他の回答 (1)

  • g_p_
  • ベストアンサー率53% (28/52)
回答No.2

こんにちは、 ・文字クラスの範囲指定がかなりテキトー(よく知りません) ・エスケープ済みの定義がかなりテキトー(これが難しいですね) ・なんか効率ワルソ-(文字+エスケープ用の\を一つずつ見てる) なんですけど、こんなんダメですか? (shiftjisで保存してActivePerlで実行) #!perl use strict; use warnings; while ( my $line = <DATA> ) { chomp $line; my $escaped; while ( $line =~ /( [\x00-\x7F] | [\x81-\xFC]\x5C{2} | [\x81-\xFC][\x40-\xFC] )/gmx ) { my $chars = $1; # print $chars , " => "; $chars =~ s/\x5C$/\x5C\x5C/ if length $chars == 2; # print $chars , "\n"; $escaped .= $chars; } print $escaped , "\n"; } __DATA__ さっき\100で買ってきた申告予想データのソースをSTDOUTに十行表示する。 さっき\100で買ってきた申\告予\想データのソ\ースをSTDOUTに十\行表\示する。

k17s
質問者

お礼

回答ありがとうございます。 おみごとです。わかりにくい質問文で申し訳なかったのですが、自分の意図した動作が見事に再現されています(笑 このソースにて $line =~ /( [\x00-\x7F] | [\x81-\xFC]\x5C{2} | [\x81-\xFC][\x40-\xFC] )/gmx がマッチしたのにもかかわらずNo.1の方の回答にあった正規表現がなぜマッチしなかったのかわからず再度ためしてみたところ正常動作いたしました・・・。 binmodeとか関係なかったっぽいですね・・大変失礼致しました。(汗 煮詰まっていたので大変助かりました。一歩前進です。 関係はあるのですが、質問とはまた違った疑問があるのでそれは別スレにて質問させていただきます。 本当にありがとうございました。

関連するQ&A