• ベストアンサー

正規表現について

任意の文字は「.」であらわされるようですが、とほほさんのサイトによると、\nは除いた任意の文字とあります。\nも含んだ任意の文字はどう表現すればいいのでしょうか? .|\n でいいんでしょうか? テキストファイルを$dataに読み込み、<start>と<end>にはさまれた改行を含む文字列を取得しようと、 if($text =~ /<start>(.*)<end>/){  print $1; } としたのですが、if文に引っかかりません。さらに、 if($text =~ /<start>([.\n]*)<end>/){  print $1; } かな?と思いましたがこれもできませんでした。 何かいい方法はないでしょうか?

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

  • ベストアンサー
  • meeee
  • ベストアンサー率31% (6/19)
回答No.1

もしファイルからwhile(<>)で読み込むとしたら、そもそも<start>aaa\nbbb<end>のような場合、 <start>aaa と bbb<end> の2行になってしまいませんか? 対象のファイルが十分小さいことが保障されている場合を除いて、ファイル全体を変数に読み込むのを前提にするのは、危険だと思いますので。 そうすると、 <start>(.*)<end>の場合は$1、 <start>(.*)\nの場合は$1\nを一時格納して、フラグを立てて、(.*)<end>が来るまでを格納する、のようにするのがよいような気がします。 1行に <start>aaa<end><start>bbb<end> となっている場合なども考えると、正規表現一発!というわけにはいかず、<start>から以降<end>が来るまでを変数に格納していく、という方法になるのではないかという予感がします。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • fo-o
  • ベストアンサー率50% (4/8)
回答No.3

if($text =~ /<start>([\S\n]*)<end>/){  print $1; } でどうでしょうか? タブとかも含めるなら ([\S\s]*) で。

すると、全ての回答が全文表示されます。
  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.2

こんばんは。 ファイル全体をメモリに読み込んで構わないのだったら楽な方法はあります。 この場合、「/.../」の後ろに「s」をつける「単独行モード」でマッチさせます。 /s には、複数の行をまとめて一つの行として扱う働きがあり, ドットは改行も含むすべての文字とマッチするようになります。 >$text =~ /<start>(.*)<end>/ を $text =~ /<start>(.*)<end>/s のように書き直して試してみましょう。 オライリーの「詳説 正規表現 第2版」(Jeffrey E. F. Friedl 著)には このあたりの詳細が述べられていますので、ご一読をお勧めします(第7章)。 http://www.oreilly.co.jp/BOOK/regex2/ なお、正規表現のみに頼った方法では構造を持った文書、 例えば「<start>外側です<start>ここは内側<end>また外に出た<end>」のように タグが入れ子になっている文書には通用しないでしょう。

参考URL:
http://www.kt.rim.or.jp/~kbk/perl5.005/perlre.html,http://www2.famille.ne.jp/~akio1998/l_grep.html
すると、全ての回答が全文表示されます。

関連するQ&A