重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

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に変化がありません。(あいうえお も消えてしまう)

何か思い当たる点がありましたら教えてください。よろしくお願いいたします。

A 回答 (3件)

正規表現の[~] の中で全角文字を使っているのが原因でしょう。


たとえば、%はEUCで \xa1\xf3 ですから、[%%] は、「\x25 か \xa1 か \xf3」という1バイトにマッチします。
そういう場合は、
正規表現を [\!\#\%\-…]|!|%|-|… といった感じで、
全角文字は | で並べる形にするのがいいでしょう。

あるいは、一手間かかりますが、エンコーディングの処理をして、
スクリプトはuse utf8しておけば、
$ascii|$twoBytes|$threeByte みたいな文字の境目チェックは不要で、
$data =~ /[!#%]/ と書くだけでも全角文字にマッチさせられます。

この回答への補足

おおおおお!!!!
うまくいきました!!

ただ、性能はものすごく悪いみたいです(泣

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

でも できてすっきりしました!

ありがとうございました!!

補足日時:2009/08/16 02:05
    • good
    • 0

もちろん Perl でもできます>#1.


というか, その方が普通.
    • good
    • 0

こんにちは


 たぶん、UNIX系の環境ですよね。
 なかなかメッセージが付かないようなのでにぎやかしということで(^^;

 難しく考えないで $pattern の文字があったら繰返し削除じゃだめですか?
 例えば、sed だったら 「s/$pattern//g」という雰囲気 (sedですから、当然 $pattern は展開して記述しますけど)。
 perl でも同様にできないでしょうかね。 コードを眺めたらできそうな気がしましたので。

 それと\でエスケープするメタ文字ってそんなに多かったですか?
/*+.,?$\[]^{}|() ←16文字よりありましたっけ?

 外してたら、ごめんなさい。

この回答への補足

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

補足日時:2009/08/16 02:04
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!