2013-10-10 85 views
1

我想使用preg_match_all从一段HTML代码中提取所有的URL。我也试图忽略所有图像。PHP的正则表达式匹配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); 
} 

在$链接阵列上面的例子应该包含:

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

谷歌被排除在外,因为它包含的.JPG图像扩展。

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

它好像百分号引起的preg_match掰开URL并提取下面的“链接”:当我添加图像像这样一个HTML $出现该问题。

http://www.google.com/image 

任何想法如何抓住唯一的网址是不是图像? (即使它们包含通常可能具有的特殊字符)

+0

停止使用正则表达式。 – 2013-10-10 01:38:41

+0

今天早些时候提出了这个问题。 '%20'是空格的URL编码。可能你的正则表达式与_space_匹配,而不是字面的“%20”。它停止在这个空间,因为这正是那个正则表达式所说的:'[^“<>] +'。 –

+1

”停止使用正则表达式“ - 你有另一个建议吗? – user1647347

回答

0

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

  1. 负载使用DOM
  2. 提取使用XPath从链接的href属性的URL的HTML(仅当你想他们,太)
  3. 从使用XPath
  4. 使用正则表达式的文本节点上的DOM提取文本节点值以匹配的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" 
}