人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPのpreg_match_allで、正規表現チェッカーとEclipseの結果が異なりうまくいかなく困ってます

HTMLの<table>内の<tr><td>から必要な情報を取得したいのですが、
正規表現チェッカーでは正しい結果が 2次元配列に繰り返しで入るのですが、
Eclipseでは、全体がarray[0][0]にマッチしてしまい、array[1][0]、array[2][0]... は最終行しか取れてない状況です。

元データ

<tr class="a"><td class="b">1</td><td class="c">1</td><td class="d"><a href="test1">test1</a></td><td class="e">1</td><td class="f"><a href="test1">test1</a></td></tr>
<tr class="a"><td class="b">2</td><td class="c">2</td><td class="d"><a href="test2">test2</a></td><td class="e">2</td><td class="f"><a href="test2">test2</a></td></tr>
<tr class="a"><td class="b">3</td><td class="c">3</td><td class="d"><a href="test3">test3</a></td><td class="e">3</td><td class="f"><a href="test3">test3</a></td></tr>


正規表現

preg_match_all('@<tr.*><td.*>(.*)<\/td><td.*>(.*)<\/td><td.*>(<a.*>.*<\/a>)<\/td><td.*>(.*)<\/td><td.*>(<a.*>.*<\/a>)<\/td><\/tr>@', $html, $matches);


htmlは mb_convert_encodingでUTF-8に変更してから、改行、タブを削除してます。

どなたかわかる方いらっしゃいましたらご教授お願いします。


●質問者: sironeko12
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● a-kuma3
ベストアンサー
\s*(.*)\s*

の部分、こうしてみたらどうでしょう。

\s*([^<\s]*)\s*





追記です。
正規表現チェッカー云々のくだりがよく分かりませんが、「全体がarray[0][0]にマッチしてしまい」は正しい動作です。
正確には「全体が」ではなく、「ほぼ全体が」ですが。

期待している通りにならないのは、.* が強くマッチするからです。
かっこの中だけではなく、タグの属性だけを引き当てているつもりの部分も。
ひとつひとつ直した方が、後々のため(プログラムの寿命がよく分かりませんが)良いと思いますが、U フラグを使う手もあります。

<?php
 $html = '<tr class="a"><td class="b">1</td><td class="c">1</td><td class="d"><a href="test1">test1</a></td><td class="e">1</td><td class="f"><a href="test1">test1</a></td></tr><tr class="a"><td class="b">2</td><td class="c">2</td><td class="d"><a href="test2">test2</a></td><td class="e">2</td><td class="f"><a href="test2">test2</a></td></tr><tr class="a"><td class="b">3</td><td class="c">3</td><td class="d"><a href="test3">test3</a></td><td class="e">3</td><td class="f"><a href="test3">test3</a></td></tr>';
 preg_match_all('@<tr.*><td.*>(.*)<\/td><td.*>(.*)<\/td><td.*>(<a.*>.*<\/a>)<\/td><td.*>(.*)<\/td><td.*>(<a.*>.*<\/a>)<\/td><\/tr>@U', $html, $matches);
 var_dump($matches);
array(6) {
 [0]=>
 array(3) {
 [0]=>
 string(167) "<tr class="a"><td class="b">1</td><td class="c">1</td><td class="d"><a href="test1">test1</a></td><td class="e">1</td><td class="f"><a href="test1">test1</a></td></tr>"
 [1]=>
 string(167) "<tr class="a"><td class="b">2</td><td class="c">2</td><td class="d"><a href="test2">test2</a></td><td class="e">2</td><td class="f"><a href="test2">test2</a></td></tr>"
 [2]=>
 string(167) "<tr class="a"><td class="b">3</td><td class="c">3</td><td class="d"><a href="test3">test3</a></td><td class="e">3</td><td class="f"><a href="test3">test3</a></td></tr>"
 }
 [1]=>
 array(3) {
 [0]=>
 string(1) "1"
 [1]=>
 string(1) "2"
 [2]=>
 string(1) "3"
 }
 [2]=>
 array(3) {
 [0]=>
 string(1) "1"
 [1]=>
 string(1) "2"
 [2]=>
 string(1) "3"
 }
 [3]=>
 array(3) {
 [0]=>
 string(25) "<a href="test1">test1</a>"
 [1]=>
 string(25) "<a href="test2">test2</a>"
 [2]=>
 string(25) "<a href="test3">test3</a>"
 }
 [4]=>
 array(3) {
 [0]=>
 string(1) "1"
 [1]=>
 string(1) "2"
 [2]=>
 string(1) "3"
 }
 [5]=>
 array(3) {
 [0]=>
 string(25) "<a href="test1">test1</a>"
 [1]=>
 string(25) "<a href="test2">test2</a>"
 [2]=>
 string(25) "<a href="test3">test3</a>"
 }
}

http://ideone.com/z8my8G


sironeko12さんのコメント
\s*([^<\s]*)\s* で試してみましたが、マッチしなく、 \s*([^<]*)\s* にすると、全100行中、半分ぐらいにマッチする感じです。

a-kuma3さんのコメント
元データが分からないと、きっちりした答えはできないですね。

sironeko12さんのコメント
元データを記載しました。

a-kuma3さんのコメント
回答に追記しました。

sironeko12さんのコメント
「.*」が強くマッチしているんですね。 「.*」はなるべく最小限にするか、タグの属性が一部一定ではないですし、 td a /a /tdで入れ子なのか td /td td /tdのように連続しているのかで 今回は全体マッチが優先され、部分マッチができないようなので 今回は Uオプションを使う方法が無難なようです

a-kuma3さんのコメント
&lt; class="a"&gt;&lt;td class=... で &lt; class="a"&gt; にだけマッチさせたい場合には、 >|| <tr.*> ||< を >|| <tr[^>]*> ||< か >|| <tr.*?> ||< というようにします。

sironeko12さんのコメント
<tr[^>]*> という方法もあるんですね。 上記ではうまくいきませんでしたが、 同じようなものを探していたところ、以下のような方法があり、 こちらの方法だとうまくいきました。 >|php| preg_match_all('@<tr[^>]*>(.*?)<\/tr>@is', $html, $lines); $result = array(); foreach ($lines[1] as $k => $line) { preg_match_all('@<td[^>]*>(.*?)<\/td>@is', $lines, $cell); foreach ($cell[1] as $cell) { $result[$k][] = trim($cell); } } ||< いろいろご教授頂きありがとうございました。

関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ