2012-11-22 51 views
0

正則表達式我有一個問題,使用正則表達式時存在的:與preg_match_all

php> $html = "<html><head><body><h1>hello world</h1><img src=\"data:rawIMGdata\" /><p/><img src=\"sdfsdf.jpg\" title=\"pic1\" /><p/><div class=\"myclass\"><img src=\"data:imageData\" /></div><img alt=\"bla\" src=\"bla.jpg\" title=\"bla\" /></body></html>"; 
php> $pat = '/<img.*src="(data:.*)"/m'; 
php> preg_match_all($pat, $html, $matching); 
php> var_dump($matching); 
array(2) { 
    [0]=> 
    array(1) { 
    [0]=> 
    string(169) "<img src="data:rawIMGdata" /><p/><img src="sdfsdf.jpg" title="pic1" /><p/><div class="myclass"><img src="data:imageData" /></div><img alt="bla" src="bla.jpg" title="bla"" 
    } 
    [1]=> 
    array(1) { 
    [0]=> 
    string(63) "data:imageData" /></div><img alt="bla" src="bla.jpg" title="bla" 
    } 
} 

我的預期輸出將只是一個occurence「數據:爲imageData」第二陣列中,而且應該有兩場比賽( 「data:rawIMGdata」)

我是否用錯誤的方式定義了我的正則表達式?

問候, Broncko

回答

1

你可能要考慮使用DOM文檔解析HTML,但如果這個例子是因爲它是會得到那麼你也許可以逃脫正則表達式複雜; DOM文檔將始終更加強大。

試試這個:

/<img.*?src="(data:[^"]*)"/m 

的?設置*爲非貪婪(所以它會得到最小匹配,默認情況下它會盡可能多地抓取它)

而不是匹配任何東西,你可以匹配任何不是「與[^ 「。 。

的*之前曾是貪婪和匹配到「在另一個元素

+0

爲我的偉大工程!猜猜我必須深入一點正則表達式。 Thx – Broncko

1

你基本上告訴PCRE抓取太多的信息,正則表達式匹配運算符會盡可能地匹配,這就是爲什麼你在匹配中獲得了很多額外的東西:首先,切換到使用非貪婪變體來匹配初始w hitespace和/或匹配元素的內容。其次,引入一個適當的分隔符來匹配屬性內容的末尾。下面是你應該使用模式:

$pat = '/<img.*?src="(data:[^"]*)"/m'; 
1

如果你試圖解析有效(幾乎無效),HTML,你可以嘗試使用tools just for parsing XMLDOM它允許您非常有效瀏覽低谷XML。

正則表達式肯定會做的工作,但一旦你換'"或HTML變化從<img src=""><img class="" src="">您可能會出現問題。

XML解析實用程序通常還會關注轉義和「無法解析」參數,處理重複的參數。

例如使用DOMxPath(這裏的[tutorial]):

$doc = new DOMDocument; 
$doc->Load('book.xml'); 
$xpath = new DOMXPath($doc); 
$query = '//img'; 

$entries = $xpath->query($query); 

foreach ($entries as $entry) { 
    if(!$entry->hasElement('src')){ 
     continue; 
    } 

    $src = $entry->getAttribute('src'); 

    if(strncmp($src, 'data:', 5) != 0){ 
     continue; 
    } 

    $content = substr($src, 5); 

    // Do whatever you need 
} 
+0

簡單:HTML解析器可能無法解析HTML。 OP的例子可能是,但這並不能保證他們可能通過代碼所做的一切都將是。 –

+0

'DOMDocument :: loadHTML()'解析janky標記的工作非常合理,但它遠非完美。與DOMDocument :: loadHTML()相比,瀏覽器解析器傾向於採用更加令人沮喪的解析方法,並且試圖解析任何東西,不管它有多糟糕。'DOMDocument :: loadHTML()'做了一個合理的工作,所有的事情都考慮到了,但它並沒有嘗試很難。 此外,您可以通過擴展您的XPath表達式消除了很多你的邏輯如下: // IMG [開始,用(@src,「數據」)]/@ SRC 這將評估一些'DOMAttr'對象,你可以獲取他們的'value'屬性。 –

+0

@KeithGaughan我在以前的工作中花了2年的時間從​​各個網站提取數據,其中一些html有如此糟糕,以至於讓我頭痛(所以我在這份工作中寫了大量的正則表達式)。我理解並同意,有時正則表達式是最好的(或唯一的)解決方案,如何獲得所需的數據而無需付出很大的努力,但我也相信,您應**在可能的情況下使用xml解析器(無負面影響) *應該**將每個程序員指向不同的選項(至少作爲研究材料)。 – Vyktor