プロが教える店舗&オフィスのセキュリティ対策術

Perlを勉強しているのですが正規表現についてよくわからないので教えてください。

$text="【件名】本文"

とあるときに、【】で囲まれた文字列(【】も含む)を抽出し、$textに戻したいのですがどうすればいいのでしょうか?
($textの中身を【件名】としたいのです)

よろしくお願いします。

A 回答 (5件)

$1が文字化けする件に関して。


それは、日本語の半分(半角英数分のデータ)しか取り出していないからです。正規表現は日本語用に作られていないので、全角文字も半角英数として文字を処理するはずです。
$t="あいう";
@a=split(//,$t);#あいうを一文字ごとに区切り、配列にする
foreach(@a){print $_,"\n";}
を実行すれば分かります。全て文字化けし、ループは6回繰り返されます。(全角3文字=半角6文字)
一応あれは【】の中身を取り出すことのみを考えたものだったので、以下のようにすれば何とかなります。

$text='あは【件名】本文';
$text=~s/(.*)(\【.+?\】)(.*)/$2/;
print $text,"\n";

あは、を取り出したいなら2行目の$2を$1に。本文、を取り出したいなら$3に書き換えてください。正常に出来ると思われます。
ちなみに言い忘れましたが、$数字と言う変数は、本来正規表現内でのみ有効な変数です。普段は使わないように。(print $1;はエラーにはなりませんが、しない方がいいでしょう。)
    • good
    • 0
この回答へのお礼

お忙しい中の回答本当にありがとうございます。
$1~$3まで正常に取り出すことができました。

本当にありがとうございました!
いろいろと勉強になりました!

お礼日時:2007/05/23 21:42

> $数字と言う変数は、本来正規表現内でのみ有効な変数です。

普段は使わないように。(print $1;はエラーにはなりませんが、しない方がいいでしょう。)

そりゃちと言いすぎかと。

The numbered match variables ($1, $2, $3, etc.) and the related
punctuation set ($+, $&, $`, $', and $^N) are all dynamically scoped
until the end of the enclosing block or until the next successful match,
whichever comes first. (See "Compound Statements" in perlsyn.)

NOTE: failed matches in Perl do not reset the match variables, which
makes it easier to write code that tests for a series of more specific
cases and remembers the best match.


ということで有効範囲の中にあるのなら、
「読むために」参照することは
問題ないかと。
#readonlyの変数なので代入は不可

if (/Time: (..):(..):(..)/) { # parse out values
$hours = $1;
$minutes = $2;
$seconds = $3;
}

こういう例もドキュメントにありますし。
    • good
    • 0
この回答へのお礼

回答(補足)ありがとうございます。
参考になりました!

お礼日時:2007/05/23 21:43

ソースが非常に汚い上に、正規表現の中でも文字列の置き換えと言うものを使った方法ですが、こんな感じでできました。



$text='あは【件名】本文';
$text=~s/(.+?)*(\【.+?\】)(.+?)*/$2/;
print $text,"\n";

基本的な考え方は、【】の前と後ろを別の変数に入れて、切り分けると言う感じです。
(あは【件名】本文 → $1=あは,$2=【件名】,$3=本文)
もう少しがんばれば、もうちょっとはスマートになると思います。例えばグループ化の()の前と後ろを、$数字内に代入しない、(?:)に書き換えるとか。

この回答への補足

ご回答ありがとうございます。
【】内の件名を無事取り出すことができました。

しかし、【】の前と後($1、$3)を取り出そうとした際に文字化けしてしまいうまくできません。
何か対策はあるのでしょうか??

補足日時:2007/05/23 13:36
    • good
    • 0

ご質問と補足で変数名が違うので少し混乱していますが・・・



$in{'sub'} に "【件名】本文" が入っていて、$sub に "【件名】" を取り出したいと推測してお答えします。

($sub) = $in{'sub'} =~ /(【.+?】)/;
print $sub;

これでどうでしょうか・・・
    • good
    • 0
この回答へのお礼

なんとか件名のみを取り出すことができました!
ありがとうございました!

お礼日時:2007/05/23 13:36

こんな感じでどうでしょう。



my $text = "[subject]content";
($text) = $text=~ /(\[.+?\])/;
print $text;

この回答への補足

ご回答ありがとうございます。
試してみたのですが、表示結果が「【件名】本文」となり上手くできませんでした…。

  $in{'sub'}=$in{'comment'};
  $sub=~ /(\【.+?\】)/;

としてるのですが、どこが間違っているのでしょうか??

補足日時:2007/05/22 10:29
    • good
    • 0

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