1

我正在尝试使用 preg_match_all 从 HTML 代码块中提取所有 url。我也试图忽略所有图像。

示例 HTML 块:

$html = '<p>This is a test</p><br>http://www.facebook.com<br><img src="http://www.google.com/photo.jpg">www.yahoo.com https://www.aol.com<br>';

我正在使用以下内容尝试仅构建 URLS 数组。(不是图片)

if(preg_match_all('~(?:(?:https://)|(?:http://)|(?:www\.))(?![^" ]*(?:jpg|png|gif|"))[^" <>]+~', $html, $links))
{ 
 print_r($links); 
}

在上面的示例中,$links 数组应包含:

http://www.facebook.com, www.yahoo.com, https://www.aol.com 

Google 被排除在外,因为它包含 .jpg 图像扩展名。当我将这样的图像添加到 $html 时,会出现问题:

<img src="http://www.google.com/image%201.jpg">

似乎百分号导致 preg_match 分解 URL 并提取以下“链接”。

http://www.google.com/image 

知道如何只抓取不是图像的网址吗?(即使它们包含 url 通常具有的特殊字符)

4

1 回答 1

0

使用 DOM 可以让您识别 HTML 文档的结构。在您的情况下,识别您想要从中获取网址的部分。

  1. 使用 DOM 加载 HTML
  2. 使用 Xpath 从链接 href 属性中获取 url(仅当您也需要它们时)
  3. 使用 Xpath 从 DOM 中获取文本节点
  4. 在文本节点值上使用 RegEx 来匹配 url

这是一个示例实现:

$html = <<<'HTML'
  <p>This is a test</p>
  <br>
  http://www.facebook.com
  <br>
  <img src="http://www.google.com/photo.jpg">
  www.yahoo.com 
  https://www.aol.com
  <a href="http://www.google.com">Link</a>
  <!-- http://comment.ingored.url -->
  <br>
HTML;

$urls = array();

$dom = new DOMDocument();
$dom->loadHtml($html);
$xpath = new DOMXpath($dom);

// fetch urls from link href attributes
foreach ($xpath->evaluate('//a[@href]/@href') as $href) {
  $urls[] = $href->value;
}

// fetch urls inside text nodes
$pattern = '(
 (?:(?:https?://)|(?:www\.))
 (?:[^"\'\\s]+)
)xS';
foreach ($xpath->evaluate('/html/body//text()') as $text) {
  $matches = array();
  preg_match_all($pattern, $text->nodeValue, $matches);
  foreach ($matches[0] as $href) {
    $urls[] = $href;
  }
}

var_dump($urls);

输出:

array(4) {
  [0]=>
  string(21) "http://www.google.com"
  [1]=>
  string(23) "http://www.facebook.com"
  [2]=>
  string(13) "www.yahoo.com"
  [3]=>
  string(19) "https://www.aol.com"
}
于 2013-11-21T21:05:14.280 回答