2012-03-22 11 views
0

私は最終的にsedとは対照的にこの目的のためにperlの使用を承認するように私の上司を得ました。Perl非貪欲なRegex

ここに基本的な質問があります。

私はこのような行があります。

<div class="SectionText">Sometext</div><div class="SectionText">Some more text</div> 

それはひどく厄介だが、私はそれを書いていないし。いずれにせよ、このようなページの立派な数があり、彼らはこの形式に変更する必要があります

<p>Sometext</p><p>Some more text</p> 

これは明らかに非貪欲にする必要があります。

perl -nle "s/(.*)<div class=\"SectionText\">(.*?)<\/div>(.*)/\1<p>\2<\/p>\3/ig; print $1" "somefile.html" > otherfile.html 

しかし、これは何もしませんし、SectionTextすべてのタグがまだ残っている:今、ここに私はこれを支援するために作ってみたラインです。

+0

あなたは貪欲ではなく、正規表現の始め、途中、そして終わりに '。* 'を入れておく必要があると言います。また、実際のHTMLパーサーを使用したくないのですか? –

答えて

6

正規表現は、HTMLの処理には理想的ではありません。適切な方法は、パーサーを使用してDOMを操作することですが、シンプルで適切な振る舞いをするために正規表現を使うことができます。これは、設計上の弱点であり予期しない問題を引き起こす可能性があることを、さらに深く理解しておいてください。

編集する領域外のテキストをキャプチャして復元する必要はありません。 <div>要素を同じ内容の<p>要素に置き換えてください。別のデリミタを選択する限り、二重引用符やスラッシュをエスケープする必要もありません。

交換文字列に\1,\2などを使用することも間違いです。 $1,$2などがここに属しており、コマンドラインで-wを使用した場合は、これが警告されていました。

これはあなたのため

perl -pe 's|<div class="SectionText">(.*?)</div>|<p>$1</p>|ig' somefile.html > otherfile.html 
+0

ありがとう!これはうまく動作します! –

4

を動作するはずですがHTML::TreeBuilder::XPath、および出力方法についてHTML::Elementを参照してください。

my $t = HTML::TreeBuilder::XPath 
    ->new_from_content('<div class="SectionText">Sometext</div><div class="SectionText">Some more text</div>'); 
for ($t->findnodes('//div[@class="SectionText"]')) { 
    $_->tag('p'); 
    $_->attr(class => undef); 
} 

は、それが100%正しいようにするには、class属性値が空白で分割されなければならない、クラス名SectionTextを除去した後、属性値を再組み立て。あなたの場合は、上記のコードのようにclass属性を削除するだけで済むと思います。

関連する問題