2010-12-27 9 views
2

における単一preg_match_allで複数のパターンを探しますうまく:PHPとpreg_match_allは、私は、次のタグ(ともタグ)との間のすべてのHTMLコンテンツを取得しようとしている使用してPHP

preg_match_all("(<p>(.*)</p>)siU", $content, $matches, PREG_SET_ORDER); 

は、単一のプリプレグを持つすべての

<p></p> <ul></ul> <table></table> 

コンテンツを取得する方法はあります_match_all?私は彼らが見つかった順番に出てくる必要があるので、私は内容をエコーすることができ、それは意味をなさないでしょう。

<p>paragraph text</p> 
<ul><li>item 1</li><li>item 2</li></ul> 
<table><tr><td>table content</td></tr></table> 
+2

のためのこの1つの作業は、[XMLパーサを使用してください。](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454) – eykanal

+0

@mario:実際にはちょっと誇張されています。重要な点は、「正規表現は、HTMLで採用されている構文を理解するには十分に洗練されていないツールです.HTMLは正規言語ではないため、正規表現では解析できません」 – netcoder

+0

[XMLパーサーを使用する](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454)(先に進む、フラグこのコメントもあります) – Will

答えて

8

利用|文字列のグループの一つと一致する:p|ul|table

使用後方参照を、私は上記の内容にpreg_match_allをしたのであれば、その後$それはエコーう配列と一致して反復

グループ(pl|ul|table)に第2のかっこが含まれているため、適切な終了タグと一致するようにします。

すべてをまとめて:

preg_match_all("(<(p|ul|table)>(.*)</\\2>)siU", $content, $matches, PREG_SET_ORDER); 

これは、入力HTMLが非常に厳密な構造に従っている場合にのみ有効です。タグにスペースを入れることも、タグに属性を付けることもできません。また、ネスティングがあると失敗します。適切な仕事をするためにhtmlパーサを使用することを検討してください。

0

正規表現ではdoableですが、単純なHTMLパーサツールキットのいずれかを使用すると、タスクを簡略化できます。あなたはDOMパーサーを使用している場合

qp($html)->find("p, ul, table")->text(); // or loop over them 
1

、そして、あなたがしなければならない、ここに方法は次のとおりです。phpQueryまたはQueryPathと例えば、それは同じくらい簡単です。貢献者は、私は、次の例で使用するuseful function for obtaining a DOMNode's innerHTMLを投稿:

$dom = new DOMDocument; 
$dom->loadHTML($html); 

$p = $dom->getElementsByTagName('p')->item(0); // first <p> node 
$ul = $dom->getElementsByTagName('ul')->item(0); // first <ul> node 
$table = $dom->getElementsByTagName('table')->item(0); // first <table> node 

echo DOMinnerHTML($p); 
echo DOMinnerHTML($ul); 
echo DOMinnerHTML($table); 
4

preg_match_all("#<\b(p|ul|table)\b[^>]*>(.*?)</\b(p|ul|table)\b>#si", $content, $matches) 
関連する問題