• ベストアンサー

perlで記号除去を行いたいのですがうまく行かない

perlで記号除去を行いたいのですがうまく行かず困っています。 文字列はEUCです。そこから$patternのような記号を削除したいのですが・・・。 http://www.din.or.jp/~ohzaki/perl.htm#Character 正しくパターンマッチさせる を参考に $ascii = '[\x00-\x7F]'; $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]'; $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]'; $pattern=q([\!!\##\%%\--―ーー・・\//\;;\??\\¥__`‘\{{\}}\++\((\))\[[\] ]\**@@\$$&&\::\>>\<<\~ ̄\^^\"”\'’  \,,\..\==\||\、、\。。]); if ($data =~ s/((?:$ascii|$twoBytes|$threeBytes)*?)(?:$pattern)/$1/mg) { print "マッチした $& \n"; } print $data; として$dataに下の2つを与えてみました。 サンプル1 【あいうえお】 サンプル2 【aaa】 ところが・・・ サンプル1 (出力なし) サンプル2 旻aaa桿 何が悪いのかわかりません・・・ ためしにパターンに【】を追加したところサンプル2はうまく行きましたが サンプル1に変化がありません。(あいうえお も消えてしまう) 何か思い当たる点がありましたら教えてください。よろしくお願いいたします。

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

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

正規表現の[~] の中で全角文字を使っているのが原因でしょう。 たとえば、%はEUCで \xa1\xf3 ですから、[%%] は、「\x25 か \xa1 か \xf3」という1バイトにマッチします。 そういう場合は、 正規表現を [\!\#\%\-…]|!|%|-|… といった感じで、 全角文字は | で並べる形にするのがいいでしょう。 あるいは、一手間かかりますが、エンコーディングの処理をして、 スクリプトはuse utf8しておけば、 $ascii|$twoBytes|$threeByte みたいな文字の境目チェックは不要で、 $data =~ /[!#%]/ と書くだけでも全角文字にマッチさせられます。

azicyan
質問者

補足

おおおおお!!!! うまくいきました!! ただ、性能はものすごく悪いみたいです(泣 やはり泣き別れ防止の ?:$ascii|$twoBytes|$threeBytes のあたりがよくないみたいですね。 あまり文字列が長いとコアダンプするし・・・ # ただし、最近のlinuxではコアダンプしないみたいです。 でも できてすっきりしました! ありがとうございました!!

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

もちろん Perl でもできます>#1. というか, その方が普通.

  • A88No8
  • ベストアンサー率52% (836/1606)
回答No.1

こんにちは  たぶん、UNIX系の環境ですよね。  なかなかメッセージが付かないようなのでにぎやかしということで(^^;  難しく考えないで $pattern の文字があったら繰返し削除じゃだめですか?  例えば、sed だったら 「s/$pattern//g」という雰囲気 (sedですから、当然 $pattern は展開して記述しますけど)。  perl でも同様にできないでしょうかね。 コードを眺めたらできそうな気がしましたので。  それと\でエスケープするメタ文字ってそんなに多かったですか? /*+.,?$\[]^{}|() ←16文字よりありましたっけ?  外してたら、ごめんなさい。

azicyan
質問者

補足

回答ありがとうございます。 展開して書くということは、 1文字ずつ書くということでしょうか?