• ベストアンサー

行頭語による判別を含んだ、正規表現による置換

条件つきの正規表現がうまく組めず困っております。 以下のような条件で、テキストファイルを置換しようとしております。 置換 (1) 全角英数字を半角化 (2) 半角カナを全角化 (3) & , " などの記号を文字参照(&など)化   置換対象の種類は百程度あり、半角記号や全角機種依存文字など各種 警告 ・ 第三/四水準文字や、特定の文字コードの文字があれば警告 処理対象条件 A 置換対象のファイルは shift-jis B ファイル内には、機種依存文字、第三/四水準文字が含まれる C ファイル内の行が[en]から始まっていたら置換対象とする   ファイル内の行が[ja]から始まっていたら別の置換条件で置換する D ファイル内の行が[lang=en]だったら、次の行を置換対象とする   ファイル内の行が[lang=ja]だったら、次の行を別の置換条件で置換する 上記のような条件となっております。  当初、処理対象の条件がAとBだけだった時は、 ([0-9A-Za-z !”#$%&’()*+,-./:;<=>?@[¥]^_`{|} ̄]) → 半角化 (ガ|ギ|グ|ゲ|ゴ|ザ|ジ|ズ|ゼ|ゾ|ダ|ヂ|ヅ|デ|ド|バ|ビ|ブ|ベ|ボ|パ|ピ|プ|ペ|ポ|ヴ) → 全角化 などと一種類ずつ置換条件を書いて、置換と警告が出来ておりました。  しかしCとDの条件が追加されたため、うまくいかずに困っております。 ^(^ja-|^ja-)(.*?)([0-9A-Za-z !”#$%&’()*+,-./:;<=>?@[¥]^_`{|} ̄]+)  このような抽出条件を書いたりしましたが、置換対象と非対称が何度も交互に出る場合などに対応できておりません。  なお、CとDを含まない条件下では以下のフリーウェアを利用して置換処理をおこなっております。 http://www.sirmiles.com/repl_ace/  当初は Perl で開発しておりましたが、 ・ 第三水準文字などが入った時にファイル出力できなかったこと ・ 文字境界の問題か、全く同じ文字に対して置換できる場合とできない場合があったこと などにより上記フリーウェアの利用といたしました。  上記や処理対象条件のAが解決すれば、行頭語の判断は if 文のみでいけるのでPerlの芽もありだと思うのですが……  現在調査を進めている方策は、以下3点です。 1 正規表現のみで行頭条件分岐+全置換の仕方を見つけて、これまで使っていたフリーウェアで実施。 2 現在は全く知識がないのだが、秀丸マクロでプログラムを組む  (サブフォルダを含めファイルの一括処理、行単位での処理、行頭の判別、半角化や全角化などなど……) 3 第三水準文字などの扱いと、置換できる場合とできない場合の調査を行いPerlで開発 (優先順位としては 1>2>3 な感じですが、1は現在行き詰まり2で調査や試行錯誤中です)  どなたか詳しい方にご意見・可否などいただければ幸いです。  時間もなく、日中もネットにつながらないために返信も遅いかもしれませぬが、よろしければお知恵をお貸しください。

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

  • ベストアンサー
  • yuuki0229
  • ベストアンサー率70% (33/47)
回答No.2

1の方法で解決可能です。 そのソフトのドキュメントで言うとこのあたりの技術を使います。 http://www.sirmiles.com/repl_ace/readme/contents/regex_7.html 簡潔な例に置き換えますが 「ja-」で始まる行の小文字アルファベットを全て大文字にするなら以下の正規表現で対応します。 検索文字列:(?<=^ja-.*)([a-z]) 置換文字列:${CONV_Upper($1)} オプション:正規表現を使う、行モード 「lang=ja」の行の次の行の小文字アルファベットを全て大文字にするなら以下の正規表現で対応します。 検索文字列:(?<=^lang=ja\r\n.*)([a-z]) 置換文字列:${CONV_Upper($1)} オプション:正規表現を使う、行モード ちなみにPerl5系では(?<=)内に可変長のパターンが置けません。 そのソフトが使用している正規表現エンジンで運良く対応していたため実現できたという形です。

suzukiri
質問者

お礼

>yuuki0229様  ご回答ありがとうございます。  (?<= ですと1度マッチした後にも、同一行内で再び行頭が一致しているかどうかを条件とするんですね。  自分で調べた時は何度も交互に出る場合に対応できず、いっそ置換処理を何度も連打しようかと考えておりました。  お教えいただいた書式を元に、今回の置換内容にあわせて設定ファイルを作成中です。  非常に助かりました。どうもありがとうございました。

その他の回答 (1)

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.1

 ひとつひとつスクリプトを示していくと膨大になるので、よくまとめられたサイトがありますので、それを参考にして書かれるのがよいでしょう。  なお、原則としてShift_JISのままでは正規表現がうまく行きませんので、Jcode.pm等で一旦UnicodeないしEUCに変換して処理してください。(EUCでも不正にマッチすることがある。) 【参考サイト】 Perlメモ/日本語の扱い - Walrus, Digit.   http://digit.que.ne.jp/work/index.cgi?Perl%e3%83%a1%e3%83%a2%2f%e6%97%a5%e6%9c%ac%e8%aa%9e%e3%81%ae%e6%89%b1%e3%81%84#ptrouble_code 【参考サイト】 Perl正規表現雑技   http://www.din.or.jp/~ohzaki/regex.htm 【参考サイト】 Perl正規表現雑技   http://www.din.or.jp/~ohzaki/regex.htm

suzukiri
質問者

お礼

>ORUKA1951様  ご回答ありがとうございます。  Perl で shift-jis のまま行った場合、機種依存文字や第三水準文字の箇所で 以下のようなエラーが出ておりました。 "\x{fffd}" does not map to shiftjis at jst_rep.cgi line 383.  置換後のファイルを shift-jis で、機種依存文字や第三水準文字も (置換対象でなければ)原文のままで出さなければなりません。  そのため、別の文字コードに変換してしまうと、機種依存文字などが元に 戻せないかと思いました。 (Perlメモ/日本語の扱い 相互変換できない記号 のページを参照しました)  ご紹介いただいたページは、作業後に改めて勉強させていただきます。  現状では、とりあえず力押しでもなんとか置換処理を行わねばと思っております。