- ベストアンサー
対応するタグに囲まれた部分を抜き出すプログラム
与えられた文字列から、対応するタグに囲まれた部分文字列を順次抜き出していく簡潔なプログラムの書き方を探しています。 例えば、注目するタグが <b> と </b> の場合、文字列 "<b>word1</b> word2 <b>word3 word4</b>" が与えられたとき、部分文字列 "word1"、"word3 word4" を順次抜き出すようなプログラムで、特に簡潔な考え方で書かれたものに関心があります。 ただ、"<b><b>word1</b> word2 <b>word3 word4</b></b>" のように、部分文字列が他の部分文字列に埋め込まれた形を含む場合には、例えば、"word1", "word3 word4", "word1 word2 word3 word4" のように、文字列左端の方からタグを含まない部分文字列を抜きだすようなプログラムは簡潔に書けないものでしょうか? 例えば以下のようにすれば文字列右端の方から処理できると思うのですが、このような感じで、文字列左端の方から処理していくプログラムというのは書けないものかと思いました。 while($input=~s/(.*)<b>(.*?)<\/b>/$1$2/) { print "$2\n" } よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
while ($input =~ s/<b>((?:(?!<b>).)*?)<\/b>/$1/) { print "$1\n"; } という感じでどうでしょう? 記述を簡素化するため、マッチした <b> 及び </b> は削除していますので、元の文字列が必要な場合は予め退避しておいて下さい。
その他の回答 (2)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
HTMLの解析というより、対応するタグに囲まれた部分文字列を順次抜き出していくというのであれば、 Perl5.8の標準モジュールText::Balancedを使うといいと思います。 perldoc Text::Balanced して貰えばいいと思いますが、なかなかわかりにくいと思うので、 サンプルを作ってみました。 --------------------------------------------------------------- use Text::Balanced qw(extract_bracketed extract_tagged); $data="<b><b>word1</b> word2 <b>word3 word4</b></b>"; &extract($data); sub extract($){ my $text = shift; my ($match,$rest,$prefix,$start,$content,$end); while(($match,$rest,$prefix,$start,$content,$end)=extract_tagged($text, '<b>', '</b>','[^<]*')){ last if $match eq ""; #マッチしなくなった &extract($content); #ネストの処置 $content =~ s/<\/?b>//g; #表示用にタグ削除 print "$content\n"; $text=$rest; #残りのマッチをさせる準備 } } ---------------------------------------------------------------- サンプルでは、printしてますけど、必要なら配列にpushすればいいと思います。 また、extract_bracketedで対になるカッコへのマッチングを扱えます。(日本語の「」を扱うためにはextract_taggedの方が良いかも知れません) あと、用途によって、同類の関数が他にも含まれています。
お礼
回答、それに丁寧な例と説明まで書いていただいてありがとうございます。 Text::Balanced という便利なものがあるのですね。いつも回答を参考にさせていただいているのですが、今回も参考になりました。 ありがとうございました。
- osamuy
- ベストアンサー率42% (1231/2878)
HTML::Parserや、HTML::TreeBuilderを使って、HTMLの構造解析を行った上で、情報抽出してみては。
お礼
アドバイスありがとうございます。 タグの種類が少ない場合(例えば、<b>と</b>だけのとき)、ごく簡潔な正規表現で用が足りるのではないかと考えたのですが、よい考えが浮かびませんでした。 <b>...</b>に限らず、例えば、(...)や「...」の場合についての方法に関心があるのですが、<b>...</b>の場合の方が、より一般的な形の回答をいただけるかと思いそのように質問してしました。 いずれにしても、アドバイス大変ありがとうございました。
お礼
回答ありがとうございます。 このような書き方ができるのですね! 期待した出力を得られたうえに、今後の勉強にもなりました。 ありがとうございました。