使用正則表達式來解析HTML可能不是最好的方法。
你可以看看DOMDocument::loadHTML,它可以讓你使用DOM方法處理HTML文檔(例如,如果你知道的話,也可以使用XPath查詢)。
您可能還想看看Zend_Dom
和Zend_Dom_Query
,順便說一句,如果您可以在您的應用程序中使用Zend Framework的某些部分,這是非常好的。
它們被用來獲取做functionnal測試時Zend_Test
,例如從HTML頁面獲取數據 - 而且工作得非常好;-)
這似乎在首位更難...但是,考慮到一塌糊塗一些HTML頁面,這可能是一個更明智的想法...評論後
編輯和OP的編輯
這裏有幾個關於思想的,被什麼東西開始「簡單」,輸入標籤:
- 它可以傳播翻過幾行
- 它可以有很多屬性
- condirering只有名稱和價值是你的興趣,你不得不面對的事實,這兩個可以在任何可能的順序
- 屬性可以有雙引號,單引號,甚至沒有任何角落找尋他們的價值觀
- 標籤/屬性既可以是小寫或大寫
- 標籤不總是被關閉
那麼,其中的一些點是無效的 - HTML;但仍然在最常見的網頁瀏覽器中工作,因此必須考慮它們...只有
與那些點,我不會想成爲一個書面方式正則表達式^^
但我想有可能是別人的困難我也沒多想。
在另一邊,你有DOM和XPath ......爲了讓輸入名字=「Q」(例如是this page)的值,它是這樣的一個問題:
$url = 'http://www.google.fr/search?q=test&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
// yep, not necessarily valid-html...
$xpath = new DOMXpath($dom);
$nodeList = $xpath->query('//input[@name="q"]');
if ($nodeList->length > 0) {
for ($i=0 ; $i<$nodeList->length ; $i++) {
$node = $nodeList->item($i);
var_dump($node->getAttribute('value'));
}
}
} else {
// too bad...
}
這裏重要的是什麼? XPath查詢,並且只有那個...並且裏面有靜態/常量嗎?
好吧,我說我希望有一個name
屬性等於「q
」所有<input>
。
,它就可以工作:我得到這個結果:
string 'test' (length=4)
string 'test' (length=4)
(我查了一下:有兩個輸入名稱=「Q」的頁面上^^)
我認識的頁面的結構?是絕對不;-)
我只知道我/你/我們要爲q ;-)
這就是我們得到的;-)
EDIT 2輸入標籤:和一點樂趣與選擇和選項:
嘛,只是爲了好玩,這裏就是我想出的選擇和選項:
$url = 'http://www.google.fr/language_tools?hl=fr';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
// yep, not necessarily valid-html...
$xpath = new DOMXpath($dom);
$nodeListSelects = $xpath->query('//select');
if ($nodeListSelects->length > 0) {
for ($i=0 ; $i<$nodeListSelects->length ; $i++) {
$nodeSelect = $nodeListSelects->item($i);
$name = $nodeSelect->getAttribute('name');
$nodeListOptions = $xpath->query('option[@selected="selected"]', $nodeSelect); // We want options that are inside the current select
if ($nodeListOptions->length > 0) {
for ($j=0 ; $j<$nodeListOptions->length ; $j++) {
$nodeOption = $nodeListOptions->item($j);
$value = $nodeOption->getAttribute('value');
var_dump("name='$name' => value='$value'");
}
}
}
}
} else {
// too bad...
}
而我得到一個輸出:
string 'name='sl' => value='fr'' (length=23)
string 'name='tl' => value='en'' (length=23)
string 'name='sl' => value='en'' (length=23)
string 'name='tl' => value='fr'' (length=23)
string 'name='sl' => value='en'' (length=23)
string 'name='tl' => value='fr'' (length=23)
這是我的預期。
一些解釋嗎?
好吧,首先,我得到的頁面的所有選擇標籤,並保持他們的名字在內存中。
然後,對於每個人,我得到的是它的後代(有永遠只有一個,BTW)所選擇的選項標籤。
在這裏,我有價值。
複雜一點,前面的例子...但仍然比正則表達式容易,我相信...也許10分鐘,而不是更多...我仍然不會有勇氣(瘋狂?)開始思考某種能夠做到這一點的突變正則表達式:-D
噢,作爲旁註:我仍然不知道HTML文檔的結構是什麼樣的:我有即使不採取單看它的源^^
我希望這有助於更多一點......
誰知道呢,也許我會說服你的正則表達式是不是一個很好的ID當涉及到解析HTML ...也許? ;-)
還有:玩得開心!
人們會告訴你使用一個html解析庫來將適當的DOM節點模式化爲一個關聯數組。那些人是對的。不要使用正則表達式來解析HTML。 – 2009-08-13 19:19:27