使用preg_match_all来拉取所有

时间:2012-02-12 22:51:53

标签: php regex preg-match-all

我正在尝试使用preg_match_all来扫描网页的来源,并将所有mailto:链接链接到一个数组,并将所有的链接:mailto:链接到另一个阵列。目前我正在使用:

$searches = array('reg'=>'/href(=|=\'|=\")(?!mailto)(.+)\"/i','mailto'=>'/href(=|=\'|=\")(?=mailto)(.+)\"/i');
foreach ($searches as $key=>$search)
{
    preg_match_all($search,$source,$found[$key]);
}

mailto:links搜索工作正常,但是我找不到为什么非mailto:link搜索同时提取mailto:和非mailto:链接的原因,即使是负面的预测断言。我做错了什么?

2 个答案:

答案 0 :(得分:2)

一个不太脆弱的理解方案是使用DOMDocument ......

$dom = new DOMDocument;

$dom->loadHTML($html);

$mailLinks = $nonMailLinks = array();

$a = $dom->getElementsByTagName('a');

foreach($a as $anchor) {
   if ($anchor->hasAttribute('href')) {
      $href = trim($anchor->getAttribute('href'));
      if (substr($href, 0, 7) == 'mailto:') {
            $mailLinks[] = $href;
      } else {
            $nonMailLinks[] = $href;
      }
   }
}

CodePad

答案 1 :(得分:0)

你的正则表达式寻找最短的替代方案:

 (=|=\'|=\")

您需要最后排序=,或使用更常见的:

 =[\'\"]?

替代/或以其他方式交换.+?以获得更明确/限制性[^\'\">]+。因此,负面断言不会与"mailto:

匹配的“.+”失败