【问题标题】:Extracting links from a piece of text in PHP except ignoring image links从 PHP 中的一段文本中提取链接,但忽略图像链接
【发布时间】:2015-06-19 13:26:14
【问题描述】:

我有这段文字,我想从中提取链接。一些带有标签的链接,一些会以普通格式出现。但我也有图片,我不想要它们的链接。

如何从这段文本中提取链接但忽略图像链接。所以基本上和 google.com 都应该被提取。

string(441) "<p class="fr-tag">Please visit&nbsp;https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg and this <a href="https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg" rel="nofollow">link</a>&nbsp;should be filtered and this&nbsp;http://d.pr/i/1i2Xu&nbsp;<img class="fr-fin fr-tag" alt="Image title" src="https://cft-forum.s3-us-west-2.amazonaws.com/uploads%2F1434714755338-Screen+Shot+2015-06-19+at+12.52.28.png" width="300"></p>"

我尝试了以下但不完整:

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

    $tags = $dom->getElementsByTagName('a');
    foreach ($tags as $tag) {
    $hrefs[] =  $tag->getAttribute('href'); 

【问题讨论】:

标签: php


【解决方案1】:

仅使用那一个字符串进行测试,以下对我有用:

$str =  '<p class="fr-tag">Please visit&nbsp;https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg and this <a href="https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg" rel="nofollow">link</a>&nbsp;should be filtered and this&nbsp;http://d.pr/i/1i2Xu&nbsp;<img class="fr-fin fr-tag" alt="Image title" src="https://cft-forum.s3-us-west-2.amazonaws.com/uploads%2F1434714755338-Screen+Shot+2015-06-19+at+12.52.28.png" width="300"></p>';

preg_match('~a href="(.*?)"~', $str, $strArr);

preg_match() 语句中使用a href ="..." 会返回一个数组,$strArr 包含两个值,两个指向 google 的链接。

Array
(
    [0] => a href="https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg"
    [1] => https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg
)

【讨论】:

  • 这是一个数组,存储所有匹配字符串的值。 php.net/manual/en/function.preg-match.php
  • 很好,这似乎可行,但您认为它有什么缺点吗?我正在尝试为论坛构建链接过滤器。正则表达式的哪一部分实际上忽略了图像标签?我想知道 :) 另外,您的过滤器没有提取这个:d.pr/i/1i2Xu。我也想提取纯链接。这就是挑战。
  • 在大多数情况下,这应该是一个不错的起点。我没有对数组中的数据进行大量处理,因为您从完整源处理的每个链接都可能不同,并且需要它自己独特的一组正则表达式或 if 语句。要忽略img 链接,在preg_match() 中,a href="(.*?)" 代码正在寻找由a href="..." 包围的任何文本,并且由于img 标记不遵循这种格式,我们可以跳过它。
【解决方案2】:

我会尝试这样的。

查找和删除图片标签:

$content = preg_replace("/<img[^>]+\>/i", "(image) ", $content); 

查找和收集 URL。

preg_match_all('#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $content, $match);

输出网址:

print_r($match);

祝你好运!

【讨论】:

  • 很酷,谢谢,但是您将如何合并此链接。它在问题中发布的我的 html 上显示 3,但它应该只有 2。因为有 2 个链接。您的代码不会忽略图像。
【解决方案3】:

我对此进行了更多尝试,并且有一个答案可能更适合您通过一些“未来验证”尝试做的事情

$str =  '<p class="fr-tag">Please visit&nbsp;www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg and this <a href="https://www.google.co.uk/?gfe_rd=cr&ei=9P2DVaW2BMWo8wfK74HYCg" rel="nofollow">link</a>&nbsp;should be filtered and this&nbsp;http://d.pr/i/1i2Xu&nbsp;<img class="fr-fin fr-tag" alt="Image title" src="https://cft-forum.s3-us-west-2.amazonaws.com/uploads%2F1434714755338-Screen+Shot+2015-06-19+at+12.52.28.png" width="300"></p>';
$str = str_replace('&nbsp;',' ',$str);
$strArr = explode(' ',$str);
$len =  count($strArr);

for($i = 0; $i < $len; $i++){
    if(stristr($strArr[$i],'http') || stristr($strArr[$i],"www")){
        $matches[] = $strArr[$i];
    }
}

echo "<pre>";
print_r($matches);
echo "</pre>";

我回去分析了您的字符串并注意到如果您将&amp;nbsp; 转换为空格,则可以将explode 字符串转换为数组,单步执行,如果任何元素包含httpwww 然后将它们添加到$matches 数组中以供稍后处理。输出非常干净且易于使用,并且您还可以通过这种方式摆脱大部分 html 标记。

需要注意的是,这可能不是最好的方法。除了您提供的字符串,我还没有测试过任何其他字符串,因此可以进行优化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多