【问题标题】:preg_match returns an empty string even there is a match即使有匹配项,preg_match 也会返回一个空字符串
【发布时间】:2014-05-22 16:16:22
【问题描述】:

我正在尝试提取网页中的所有元标记,目前正在使用 preg_match_all 来获取它,但不幸的是它为数组索引返回了一个空字符串。

 <?php
  $meta_tag_pattern = '/<meta(?:"[^"]*"[\'"]*|\'[^\']*\'[\'"]*|[^\'">])+>/';
  $meta_url = file_get_contents('test.html');
  if(preg_match_all($meta_tag_pattern, $meta_url, $matches) == 1)
    echo "there is a match <br>";

  print_r($matches);
?>

返回数组:

Array ( [0] => Array ( [0] => [1] => [2] => [3] => ) ) Array ( [0] => Array ( [0] => [1] => [2] => [3] => ) ) 

【问题讨论】:

  • 由于preg_match_all返回匹配的数量,我建议你只写:if(preg_match_all($meta_tag_pattern, $meta_url, $matches) )或者如果你正在寻找第一个结果,使用preg_match
  • 使用DOMDocument更容易得到你想要的结果。
  • 这就是我如何捕获元标记 /]+>/ 。你想捕捉什么?整个标签?属性?属性值?
  • @CasimiretHippolyte 我认为这可能是我的代码中的逻辑错误,所以我尝试了write if 语句的其他方法。我正在寻找一种性能方式来解析页面,这种方式我没有使用DOMDocument
  • 添加 i 标志,即不区分大小写。检查源 html 代码以确保您来自 print_r 的代码未被浏览器解析为 HTML 代码。

标签: php arrays tags preg-match-all


【解决方案1】:

DOMDocument 示例:

$url = 'test.html';

$dom = new DOMDocument();
@$dom->loadHTMLFile($url);

$metas = $dom->getElementsByTagName('meta');

foreach ($metas as $meta) {
    echo htmlspecialchars($dom->saveHTML($meta));
}

【讨论】:

  • 很好的答案。 DOMDocument 总是比其他“撕裂”方法更好。
  • @JakeGould:是的,但是使用preg_match_all 完成具有良好模式和格式不太差的html 的相同任务的速度要快100 倍。
【解决方案2】:

更新:从 URL 抓取元标记的示例:

$meta_tag_pattern = '/<meta\s[^>]+>/';
$meta_url = file_get_contents('http://stackoverflow.com/questions/10551116/html-php-escape-and-symbols-while-echoing');
if(preg_match_all($meta_tag_pattern, $meta_url, $matches))
  echo "there is a match <br>";

foreach ( $matches[0] as $value ) {
    print htmlentities($value) . '<br>';
}

输出:

there is a match 
<meta name="twitter:card" content="summary">
<meta name="twitter:domain" content="stackoverflow.com"/>
<meta name="og:type" content="website" />
...

看起来问题的一部分是浏览器将元标记呈现为元标记,并且在您 print_r 输出时不显示文本,因此需要对它们进行转义。

【讨论】:

  • 以提取stackoverflow页面的meta标签为例。
  • print_r 输出被我通过查看页面源查看的浏览器呈现为html,这就是为什么我没有看到输出并认为它是空字符串的原因。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多