【问题标题】:PHP using preg_match to get title from articlePHP 使用 preg_match 从文章中获取标题
【发布时间】:2010-08-22 14:00:00
【问题描述】:

preg_match 有一个奇怪的问题。我正在使用一个抓取文章标题的正则表达式,基本上是寻找标签:

preg_match('#(\<title.*?\>)(\n*\r*.+\n*\r*)(\<\/title.*?\>)#', $data, $matches)

当我打印出 $matches 数组时,我什么也得不到。但是当我在正则表达式测试器中尝试同样的事情时,它工作得很好。我什至尝试放入一个绝对匹配它的字符串来代替 $data 变量,但没有任何运气。

我在这里做错了什么?

【问题讨论】:

  • 您是否正在尝试匹配 XML 文件中的 标记或其他内容。您能否更具体一些,并提供一些您尝试匹配的字符串示例:)
  • 请勿使用正则表达式解析 HTML 或 XML 结构
  • 你应该改用 PHP 的原生 DOM 函数:php.net/manual/en/book.simplexml.php
  • 传入的数据是任意文章。现在我正在测试我使用 CURL 获得的一些 cnn 文章。我将该页面放入一个变量中并尝试对其进行预匹配。我知道它正确地拉入了文章,因为我可以呼应那篇文章。但即使我尝试: preg_match('#(\)(\n*\r*.+\n*\r*)(\)#' , '这是一个标题', $matches);并为 preg 匹配尝试一个简单的标题字符串,然后它仍然没有给我任何结果。
  • 如果使用 PHP 的原生 DOM 函数失败,你应该使用Simple HTML DOM parser 寻求庇护,这更容易原谅 HTML 损坏的罪过。

标签: php regex


【解决方案1】:

如果您仍想使用regex 而不是DOM,您可以这样做:

if(preg_match("/<title>(.+)<\/title>/i", $data, $matches))
     print "The title is: $matches[1]";
else
     print "The page doesn't have a title tag";

【讨论】:

  • 谢谢,这行得通。我想我只是让它太复杂了。虽然不确定为什么它会在测试器中工作而不是在实际脚本中。
  • @pfunc,我做了这个(又快又脏),它工作得很好,并显示了页面的标题。我想您必须使用echo $matches[2]; 才能使其正常工作。 $data = file_get_contents("localhost/"); preg_match('#(\)(\n*\r*.+\n*\r*)(\)#', $data, $matches); echo $matches[2];
【解决方案2】:

或者您可以使用 HTML 解析器:

$dom = new domDocument;
$dom->loadHTML($HTML);

echo $dom->getElementsByTagName('title')->item(0)->nodeValue;

【讨论】:

  • 我自己更喜欢使用 SimpleHTMLDOM 扩展,但是这种方法不需要外部库。
  • 是的,但是 DOMDocument 在标记有效性方面非常严格。它不适用于许多页面。
  • 在使用-&gt;loadHTML() 时抑制错误,您会惊讶于它处理损坏的 HTML 的能力
【解决方案3】:

为我工作:

preg_match("/<title>(.*)<\/title>/is", $html, $matches);

来自此来源: https://gist.github.com/jeremiahlee/785770

【讨论】:

    【解决方案4】:

    您可能需要用反斜杠引用您的反斜杠。

    PHP 的字符串解析器删除一层反斜杠,然后正则表达式引擎消耗另一层,因此(例如)识别一个反斜杠需要源代码中的四个。

    除此之外,您可以尝试利用 PHP 中的 XML 识别功能,或者做一些不太聪明的字符串处理。通常当 REGEX 中断时,这是因为您试图对它们过于聪明。考虑只查找 " 并删除整个标题标签,然后从字符串中删除空格,然后瞧!标题。

    另见http://php.net/manual/en/book.simplexml.php

    【讨论】:

      【解决方案5】:

      试试这个

      if (preg_match('%(<title.*?\b(?!\w))(\n*\r*.+\n*\r*)(\b(?=\w)/title.*?\b(?!\w))%', $data, $matches)) {
          $title = $matches[1];
      } else {
          $title = "";
      }
      

      【讨论】:

        【解决方案6】:

        像其他人一样,这有“使用解析器,而不是正则表达式”的免责声明。但是,如果您仍然想要正则表达式,请查看以下内容:

        $string = "<title>I am a title</title>";
        $regex = "!(<title[^>]*>)(.*)(</title>)!i";
        preg_match($regex, $string, $matches);
        print_r($matches);
        
        //should output:
        array(
            [1] => "<title>"
            [2] => "I am a title"
            [3] => "</title>"
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多