- ベストアンサー
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に変化がありません。(あいうえお も消えてしまう) 何か思い当たる点がありましたら教えてください。よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
正規表現の[~] の中で全角文字を使っているのが原因でしょう。 たとえば、%はEUCで \xa1\xf3 ですから、[%%] は、「\x25 か \xa1 か \xf3」という1バイトにマッチします。 そういう場合は、 正規表現を [\!\#\%\-…]|!|%|-|… といった感じで、 全角文字は | で並べる形にするのがいいでしょう。 あるいは、一手間かかりますが、エンコーディングの処理をして、 スクリプトはuse utf8しておけば、 $ascii|$twoBytes|$threeByte みたいな文字の境目チェックは不要で、 $data =~ /[!#%]/ と書くだけでも全角文字にマッチさせられます。
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
もちろん Perl でもできます>#1. というか, その方が普通.
- A88No8
- ベストアンサー率52% (836/1606)
こんにちは たぶん、UNIX系の環境ですよね。 なかなかメッセージが付かないようなのでにぎやかしということで(^^; 難しく考えないで $pattern の文字があったら繰返し削除じゃだめですか? 例えば、sed だったら 「s/$pattern//g」という雰囲気 (sedですから、当然 $pattern は展開して記述しますけど)。 perl でも同様にできないでしょうかね。 コードを眺めたらできそうな気がしましたので。 それと\でエスケープするメタ文字ってそんなに多かったですか? /*+.,?$\[]^{}|() ←16文字よりありましたっけ? 外してたら、ごめんなさい。
補足
回答ありがとうございます。 展開して書くということは、 1文字ずつ書くということでしょうか?
補足
おおおおお!!!! うまくいきました!! ただ、性能はものすごく悪いみたいです(泣 やはり泣き別れ防止の ?:$ascii|$twoBytes|$threeBytes のあたりがよくないみたいですね。 あまり文字列が長いとコアダンプするし・・・ # ただし、最近のlinuxではコアダンプしないみたいです。 でも できてすっきりしました! ありがとうございました!!