首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 正則表達式提取圖片、鏈接、標題完整指南

     編輯:PHP 相關知識

核心正則語法速查

元字符含義示例
.任意字符 (除換行)a.c 匹配 abc, axc
*前字符 0~n 次 (貪婪)ab*c 匹配 ac, abc, abbc
+前字符 1~n 次ab+c 匹配 abc, abbc
?前字符 0~1 次ab?c 匹配 ac, abc
.*?非貪婪匹配 (最少)<div>.*?</div> 匹配單層
(...)捕獲組 (可反向引用 $1)(\d{4})-(\d{2})
(?:...)非捕獲組 (僅分組)(?:http|https)://
[]字符類[a-zA-Z]
\d \w \s數字/單詞字符/空白

實戰 1:提取圖片 URL (支援單雙引號、屬性順序不固定)

<?php
$html = '<p><img src="img1.jpg" alt="圖1"><img alt="圖2" src=\'img2.png\' class="thumb"></p>';

// 正則解析:
// ]*        非 > 字符 (屬性區)
// src=         src 屬性
// (["'])       捕獲引號類型 (組1)
// (.*?)        非貪婪捕獲 URL (組2) - 核心目標
// \1           反向引用相同引號閉合
// [^>]*        其餘屬性
// >            標簽結束
$pattern = '/]*src=(["\'])(.*?)\1[^>]*>/i';

preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);

$images = [];
foreach ($matches as $m) {
    $images[] = [
        'quote' => $m[1],  // 引號類型
        'url'   => $m[2],  // 圖片地址
        'full'  => $m[0]   // 完整標簽
    ];
}
print_r($images);
/*
Array
(
    [0] => Array ( [quote] => " [url] => img1.jpg [full] => 圖1 )
    [1] => Array ( [quote] => ' [url] => img2.png [full] => 圖2 )
)
*/

實戰 2:提取超鏈接與鏈接文本

<?php
$html = '<a href="https://example.com" class="link">示例網站</a> 
<a id="top" href=\'https://test.org\' target="_blank">測試站點</a>';

// 正則: ]* href=(["']) (.*?) \1 [^>]* > (.*?) 
$pattern = '/]*href=(["\'])(.*?)\1[^>]*>(.*?)<\/a>/is';

preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);

$links = [];
foreach ($matches as $m) {
    $links[] = [
        'url'  => $m[2],  // href 值
        'text' => trim(strip_tags($m[3])), // 鏈接文本 (去除可能嵌套標簽)
        'full' => $m[0]
    ];
}
print_r($links);
/*
Array
(
    [0] => Array ( [url] => https://example.com [text] => 示例網站 ... )
    [1] => Array ( [url] => https://test.org [text] => 測試站點 ... )
)
*/

實戰 3:提取頁面標題 <title>

<?php
$html = '網頁標題 - 站點名稱';

$pattern = '/]*>(.*?)<\/title>/is';
if (preg_match($pattern, $html, $m)) {
    echo "標題: " . trim($m[1]); // 網頁標題 - 站點名稱
}

實戰 4:提取 meta 標簽信息 (SEO 關鍵)

<?php
$html = '<meta name="description" content="頁面描述內容">
<meta property="og:title" content="分享標題">';

$pattern = '/]*(?:name|property)=(["\'])(.*?)\1[^>]*content=\1(.*?)\1/';

preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
    echo "{$m[2]}: {$m[3]}\n";
}
// description: 頁面描述內容
// og:title: 分享標題

進階技巧:DOMDocument 替代正則 (強烈推薦)

正則解析 HTML 的局限: HTML 結構複雜 (屬性換行、註釋、CDATA、非標準閉合),正則極難覆蓋所有邊界情況。PHP 內建 DOMDocument 是專業解析器,健壯性遠超正則。
<?php
$html = '<div class="content"><img src="a.jpg"><a href="link.html">文本</a></div>';

$dom = new DOMDocument();
// 抑制非標準 HTML 產生的警告
libxml_use_internal_errors(true);
$dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();

// 1. 提取所有圖片
$images = [];
foreach ($dom->getElementsByTagName('img') as $img) {
    $images[] = $img->getAttribute('src');
}

// 2. 提取所有鏈接
$links = [];
foreach ($dom->getElementsByTagName('a') as $a) {
    $links[] = [
        'url'  => $a->getAttribute('href'),
        'text' => trim($a->textContent)
    ];
}

// 3. 提取標題
$title = $dom->getElementsByTagName('title')->item(0)?->textContent ?? '';

// 4. XPath 精準查詢 (如: 類為 thumb 的圖片)
$xpath = new DOMXPath($dom);
$thumbImages = $xpath->query('//img[contains(@class, "thumb")]');
foreach ($thumbImages as $img) { /* ... */ }

print_r(compact('images', 'links', 'title'));

常見陷阱與優化

問題解決
貪婪匹配導致跨標簽捕獲使用非貪婪 .*? 或具體字符類 [^"']*
跨行匹配失敗加 s 修飾符 (DOTALL) 讓 . 匹配換行
大小寫敏感加 i 修飾符
特殊字符轉義在字符類 [] 中 - ] ^ \ 需轉義或放首尾
性能災難 (回溯)避免嵌套量詞 (a*)*,用具體字符類替代 .*

總結建議

  1. 簡單提取 (已知結構固定): 正則表達式編寫快、執行快,適用 preg_match_all。
  2. 複雜/不規範 HTML 解析: **強制使用 DOMDocument + DOMXPath**,容錯率高、語義清晰、可維護。
  3. 大規模採集: 考慮 symfony/dom-crawler 或 sunra/php-simple-html-dom-parser 等成熟庫,支援 CSS 選擇器語法 ($crawler->filter('img.thumb')->attr('src'))。
  4. 編碼處理: loadHTML 前加 防止中文亂碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved