2010-01-14 118 views

回答

1

如果你真的想使用正則表達式,我認爲:

preg_match_all('/<h[0-6]>([^</h[0-6]>*)</h/i', $string, $matches); 

應該只要你的標題標籤沒有嵌套工作。正如其他人所說,如果你不控制HTML,正則表達式不是一個很好的方法來做到這一點。

3

當問題是「我如何從HTML中提取東西」時,答案永遠不要使用正則表達式。相反,請參閱Robust, Mature HTML Parser for PHP的討論。

+0

有沒有機會舉個例子?我需要獲取'article'div類中的所有標題標籤。我總是對DOm – bluedaniel 2010-01-14 14:44:36

2

建議不要使用正則表達式這個工作,使用的東西SimpleHTMLDOM parser

+0

感到困惑,我發現正則表達式在這方面更好。在解析HTML或無效HTML結構的網頁上,DOM解析器有點不可靠。 – 2012-10-30 07:01:43

2

你可能會更好使用HTML解析器。但對於真正簡單的場景,這樣的事情可能會做:

if (preg_match_all('/<h\d>([^<]*)<\/h\d>/iU', $str, $matches)) { 
    // $matches contains all instances of h1-h6 
} 
+0

在PHP 5.3.5上使用此片段時,出現錯誤'preg_match_all():未知修飾符'h';爲了解決這個錯誤,我用管道符號替換了正則表達式邊界:''| ([^ <]*) | iU'' – feeela 2011-08-25 14:42:07

3

請考慮本地DOMDocument php類。

您可以使用$domdoc->getElementsByTagName('h1')查看您的標題。

5

首先,你需要清理(在本例中$ html_str)的HTML與整潔:

$tidy_config = array(
    "indent"    => true, 
    "output-xml"   => true, 
    "output-xhtml"   => false, 
    "drop-empty-paras"  => false, 
    "hide-comments"  => true, 
    "numeric-entities"  => true, 
    "doctype"    => "omit", 
    "char-encoding"  => "utf8", 
    "repeated-attributes" => "keep-last" 
); 

$xml_str = tidy_repair_string($html_str, $tidy_config); 

然後您可以將XML($ xml_str)加載到一個DOMDocument:

$doc = DOMDocument::loadXML($xml_str); 

最後你可以使用Horia Dragomir的方法:

$list = $doc->getElementsByTagName("h1"); 
for ($i = 0; $i < $list->length; $i++) { 
    print($list->item($i)->nodeValue . "<br/>\n"); 
} 

或者你也可以使用XPath進行更復雜的查詢在DOM文檔(見http://www.php.net/manual/en/class.domxpath.php

$xpath = new DOMXPath($doc); 
$list = $xpath->evaluate("//h1"); 
+0

東西壞了這個劇本,用簡單的HTML喜歡嘗試「

測試


」 – bluedaniel 2010-01-14 15:04:47

+0

你什麼錯誤如果我嘗試的例子,你給它按預期工作?並打印「測試」 – CodeAddict 2010-01-14 15:17:10

+0

在所有與唯一的變化是上面的代碼:$ xml_str = tidy_repair_string(「

測試


」,$ tidy_config);它打破了我的劇本,有一個錯誤在那裏崩潰像打字錯誤 – bluedaniel 2010-01-14 15:25:23

3

我知道這是一個超級老帖子,但我想提一提我就能夠共同抓住標題標籤的最佳方式。

<h1>title</h1> and <h2>title 2</h2> 

這種方法(可以作爲一個正則表達式,但是PHP行爲有點不同。)在你的preg_match

/<\s*h[1-2](?:.*)>(.*)</\s*h/i 

使用本

|<\s*h[1-2](?:.*)>(.*)</\s*h|Ui 

$group[1]將包括曾經是什麼在標題標籤之間。 $group[0]就是一切<h1>test</h

這將佔空間,如果有人添加了 「類/ ID」

<h1 class="classname">test</h1> 

類/ ID(組)被忽略。

注意:當我分析HTML標籤時,我總是將所有空白區域,換行符,製表符等取出並用1個空格替換。這最大限度地減少了多線,dotalls ...和大量的空白,在某些情況下可能會混淆正則表達式格式。

  • 當然我只抓取1-2個標題標籤,將其更改爲0-9以全部抓取。
  • 如果其他人有一個mod來添加或修復我的代碼,請回復,我真的很想知道。
  • 相反,正則表達式對HTML不好,這是一個非常開放的論點。因爲如果你設計你的php函數和正則表達式來完美地去掉垃圾併爲正則表達式準備HTML,你將會完全能夠抓住你正在尋找的東西。你可以做出足夠的正則表達式來替代業餘html工作。

這裏是一個測試頁面regex test

+0

我想你是指'| <\ s * h [1-2](?:。*)>(。*) | Ui'否則它不會抓住整個元素並關閉結束標記> 請注意,如果在標題中出現換行符('
'),則完全可能使用用戶生成的內容 – cameronjonesweb 2017-11-07 05:44:45

0

我想和大家分享我的解決辦法的鏈接:

function get_all_headings($content) { 
    preg_match_all('/\<(h[1-6])\>(.*)<\/h[1-6]>/i', $content, $matches); 

    $r = array(); 
    if(!empty($matches[1]) && !empty($matches[2])){ 
     $tags = $matches[1]; 
     $titles = $matches[2]; 
     foreach ($tags as $i => $tag) { 
      $r[] = array('tag' => $tag, 'title' => $titles[ $i ]); 
     } 
    } 

    return $r; 
} 

這個函數會返回一個空數組,如果標題沒有找到或者是這樣的:

array (
    array (
     'tag' => 'h1', 
     'title' => 'This is a title', 
    ), 
    array (
     'tag' => 'h2', 
     'title' => 'This is the second title', 
    ), 
) 
相關問題