2015-12-21 55 views
2

這是我正在使用的正則表達式。它工作正常,但現在我試圖得到結果。當發現匹配時獲取數組的其他部分

基本上,如果名稱/屬性/ etc包含「標題」,我希望它回顯標題元標記的內容。

換句話說,當out [1]包含「title」(不區分大小寫)時,我想要相應的out [2],而不是out [1]。

$pattern = ' 
    ~<\s*meta\s 

    # using lookahead to capture type to $1 
    (?=[^>]*? 
    \b(?:name|property|http-equiv)\s*=\s* 
    (?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'| 
    ([^"\'>]*?)(?=\s*/?\s*>|\s\w+\s*=)) 
) 

    # capture content to $2 
    [^>]*?\bcontent\s*=\s* 
    (?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'| 
    ([^"\'>]*?)(?=\s*/?\s*>|\s\w+\s*=)) 
    [^>]*> 

    ~ix'; 

if(preg_match_all($pattern, $link_html, $out)) 
{ 
    foreach ($out[1] as $out) 
    { 
     echo $out.'<br>'; 
    } 
} 
+1

爲什麼不使用html解析器呢? – Gordon

回答

2

你問一個正則表達式,但使用的HTML解析器和XPath會如此更容易和更可讀:

<?php 

$html = <<< HTML 
<html> 
    <head> 
     <meta name="author" lang="en" content="Gordon" /> 
     <meta name="title" lang="en" content="match this" /> 
     <meta property="title" lang="en" content="and this" /> 
     <meta http-equiv="title" lang="en" content="and also this" /> 
     <meta foo="title" content="but not this" /> 
    </head> 
    <body>Use DOMDocument for HTML parsing instead</body> 
</html> 
HTML; 

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

$xpath = new DOMXPath($dom); 
$nodes = $xpath->evaluate(
    '//meta[ 
     @*[ 
     contains("name|property|http-equiv", name()) 
     and contains(., "title") 
     ] 
     ]/@content' 
); 

foreach ($nodes as $node) { 
    echo $node->nodeValue, PHP_EOL; 
} 

輸出:

match this 
and this 
and also this 

XPath表示找到任何元標記的所有內容屬性,其中任何屬性名稱都是字符串「name | property | http-equiv」的一部分,並且在該屬性中包含值「title」。正如你所希望看到的那樣,XPath本身幾乎讀起來就好像它是自然語言一樣(而不是你使用的正則表達式)。

+1

哦,哇,我很早以前就用過XPath,然後就忘了它......你說得很對......我會接受它的時候允許我......謝謝! :) –

1

這應該通過捕捉數組索引在foreach循環,這樣纔有可能:

foreach ($out[1] as $index => $out) { 
    if(stristr($out, 'title')) echo $out[2][$index].'<br>'; 
} 
相關問題