• ベストアンサー

Perlの正規表現で文字の抽出

Perlを勉強しているのですが正規表現についてよくわからないので教えてください。 $text="【件名】本文" とあるときに、【】で囲まれた文字列(【】も含む)を抽出し、$textに戻したいのですがどうすればいいのでしょうか? ($textの中身を【件名】としたいのです) よろしくお願いします。

  • bo281
  • お礼率19% (12/63)
  • Perl
  • 回答数5
  • ありがとう数3

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

  • ベストアンサー
  • W_H
  • ベストアンサー率47% (21/44)
回答No.4

$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;はエラーにはなりませんが、しない方がいいでしょう。)

bo281
質問者

お礼

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

その他の回答 (4)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

> $数字と言う変数は、本来正規表現内でのみ有効な変数です。普段は使わないように。(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; } こういう例もドキュメントにありますし。

bo281
質問者

お礼

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

  • W_H
  • ベストアンサー率47% (21/44)
回答No.3

ソースが非常に汚い上に、正規表現の中でも文字列の置き換えと言うものを使った方法ですが、こんな感じでできました。 $text='あは【件名】本文'; $text=~s/(.+?)*(\【.+?\】)(.+?)*/$2/; print $text,"\n"; 基本的な考え方は、【】の前と後ろを別の変数に入れて、切り分けると言う感じです。 (あは【件名】本文 → $1=あは,$2=【件名】,$3=本文) もう少しがんばれば、もうちょっとはスマートになると思います。例えばグループ化の()の前と後ろを、$数字内に代入しない、(?:)に書き換えるとか。

bo281
質問者

補足

ご回答ありがとうございます。 【】内の件名を無事取り出すことができました。 しかし、【】の前と後($1、$3)を取り出そうとした際に文字化けしてしまいうまくできません。 何か対策はあるのでしょうか??

  • SE-1
  • ベストアンサー率57% (26/45)
回答No.2

ご質問と補足で変数名が違うので少し混乱していますが・・・ $in{'sub'} に "【件名】本文" が入っていて、$sub に "【件名】" を取り出したいと推測してお答えします。 ($sub) = $in{'sub'} =~ /(【.+?】)/; print $sub; これでどうでしょうか・・・

bo281
質問者

お礼

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

  • SE-1
  • ベストアンサー率57% (26/45)
回答No.1

こんな感じでどうでしょう。 my $text = "[subject]content"; ($text) = $text=~ /(\[.+?\])/; print $text;

bo281
質問者

補足

ご回答ありがとうございます。 試してみたのですが、表示結果が「【件名】本文」となり上手くできませんでした…。   $in{'sub'}=$in{'comment'};   $sub=~ /(\【.+?\】)/; としてるのですが、どこが間違っているのでしょうか??

関連するQ&A

  • perl 正規表現 抽出

    perl の正規表現を用いて、文字列の抽出を行いたいのですがどのように 書けばいいのかわかりません。 実現したいことは 「Y:/フォルダ名/フォルダ名/ファイル名.拡張子」 というテキストに対して 「拡張子」のみを抽出することと 「ファイル名」のみを抽出することです。 パターンマッチや変換はなんとなくわかるのですが 抽出の仕方がよくわかりません。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • perlでテキストから顔文字を抽出するプログラム

    テキストファイルから顔文字を抽出するプログラムを作りたいのですが、行き詰まっています。 一応、正規表現の内容としては、 半角と全角の括弧と前後の記号っぽいものを抽出し、 括弧の中身が「3文字以上半角英数字/全角文字列が続かないもの」という条件で、 抽出すれば上手くいくのかなぁと考えているのですが、上手くperlで表現できていない状態です。 どなたかプログラムに詳しい方で、ソースを記述できる方がいれば、よろしくお願いいたします。

  • Perl正規表現(置換)

    Perlを用いてテキスト中の文字列 /^\d+$|^\d+\.[05]{1}$/ を、以下の文字列に置換したい場合、 うまくやる方法はないでしょうか? /^[0]+$|^[0]+\.[0]+$/ 正規表現を使いたいですが、 1つ1つエスケープしていくのはさすがに・・・ よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Perlの正規表現

    Perlの正規表現である文字列に文字列STRINGが含まれないようにするには ^(?!.*STRING).+$ と書くとググったら出てきました. ですが,?!について詳しいことまで書いてるサイトはありませんでした. ?!は具体的にはどのようなことをするのでしょうか?

  • PHP 正規表現 文字列抽出

    PHP 正規表現 文字列抽出のご質問です。 ある文字列の中から「○○%OFF」の○○の部分を抽出したいのですが。 分かる方いらっしゃったら、ご教授ください。

    • 締切済み
    • PHP
  • Perlの正規表現

    Perlの正規表現で質問です。 例えば、 "aabbccddee"と"cdde"という2種の文字列があるとして"cdde"だけを検索(または置換)したい場合の正規表現ってどのようにすればよいのでしょうか? いま、"cdde"で検索すると"aabbccddee"と"cdde"の2種類がヒットしてしまうのですが"cdde"だけヒットするような正規表現をどなたかご教示ください。 宜しくお願い致します。

    • ベストアンサー
    • Perl
  • Perl正規表現わかりますか?

    下記のPerl正規表現ですが、どんな意味か分かるでしょうか? $var =~ s!/([^/]+|~(\.\.))/\.\./!/!g 参考書も読んでみたのですが分かりませんでした(セットされている文字列にどんなマッチング、置換をしているのでしょう) お分かりの方いれば、よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perl・正規表現が分かりません

    Perlでプログラムを書く場合、 ある文字列の文字数が5文字且つ、文字列の先頭に[0-5A]を必ず含み、そして残り4文字にも[0-5A]のみを必ず含む場合、Trueを表示。 それ以外はErrを表示する。 多分、全て、正規表現でできると思うのですが、分かりません。教えていただけないでしょうか? 宜しくお願い致します。 $test = "0AAAA"; if(正規表現){ print "True"; }else{ print "Err"; } ↑結果:True $test = "aAAAA";の場合、 結果:Err

    • ベストアンサー
    • Perl
  • 正規表現を使った文字列の抽出方法について

    正規表現を使った文字列の抽出方法について RHELを使っています。 テキストデータの中に、以下のようなデータが 百万行単位で並んでいます。(カンマ区切り、2列構成) 1, 1.24425 2, 3.25252 (中略) 13, 6.25365 14, 8,36222 (中略) 103633, 252525.0 最終的にやりたいことは2列目のデータのみの抽出です。 考え方として、正規表現で 「<任意の文字列の連続><カンマ>」という文字列を認識させ、 それを「空欄」で置換したいと考えています。 文字列の最後の文字をマッチさせる指定子が「$」という情報をWebで見つけたので まず、grepで見つけられるか以下のようにやってみたのですが、 grep -i ",$" test.txt $が環境変数と取られ、構文エラーとなってしまいます。 使い方がおかしいのでしょうか? ちなみに、うすうす感じている疑問として、「$」は文末にくるものしかマッチしなかったり しますでしょうか? カンマ区切りなので、表計算ソフトを使えなくもないですが、 行数がExcel2007の限界をよく超えるので、それ以外の方法で考えています。 アドバイスよろしくお願いいたします。

  • 正規表現で()で括られた文字列を()ごと削除したい場合、どのように抽出

    正規表現で()で括られた文字列を()ごと削除したい場合、どのように抽出すればよいでしょうか?

専門家に質問してみよう