【问题标题】:Issue with Preg_matchPreg_match 的问题
【发布时间】:2012-12-23 17:15:56
【问题描述】:

我做了一个简单的应用程序,从allrecipes.com. 等网站获取食谱信息我正在使用preg_match,但有些东西不起作用。

$geturl = file_get_contents("http://allrecipes.com/Recipe/Brown-Sugar-Smokies/Detail.aspx?src=rotd");
          preg_match('#<title>(.*) - Allrecipes.com</title>#', $geturl, $match);
          $name = $match[1];
          echo $name;

我只是想获取页面的标题(减去- Allrecipes.com 部分)并将其放入变量中,但出现的所有内容都是空白的。

【问题讨论】:

  • 您是否尝试过打印$geturl 并查看该字符串是否确实存在?
  • 您无法对代码进行故障排除。例如,在使用返回值之前检查它们。
  • @minitech,是的,当我打印 $geturl 时,我得到了整个 Allrecipes.com 页面

标签: php preg-match


【解决方案1】:

如果您查看页面的源代码,您会注意到&lt;title&gt; 在实际文本周围包含一些填充,您需要对此进行补偿。

'#<title>\s*(.*) - Allrecipes.com\s*</title>#'

【讨论】:

    【解决方案2】:

    这种模式有两个问题。首先,&lt;title&gt; 后面有一个换行符,. 没有捕获它(因为没有/s 修饰符. 字面上是“除 EOL 之外的任何符号”)。其次,Allrecipes.com 文本后面实际上没有 &lt;/title&gt; 子字符串,它们之间有一个换行符。

    考虑到\s 涵盖了普通空格和行分隔符这一事实,您可以像这样更改您的正则表达式:

    '#<title>\s*(.*?) - Allrecipes.com\s*</title>#s'
    

    /s 修饰符实际上与此处无关(感谢 minitech 注意到这一点),因为此配方中的标题是单行的,并且所有“\n”符号都将被 \s* 子表达式覆盖。但我仍然建议把它留在那里,这样多行标题就不会让你措手不及。

    为了提高效率,我在这里将.* 替换为.*?:因为您要查找的字符串很短,所以在这里使用非贪婪量词是有意义的。

    【讨论】:

    • &lt;/title&gt; 也不会立即关注Allrecipes.com
    • 为什么 s 修饰符现在是相关的呢?配方名称没有换行符。
    • 你是对的,当然;我虽然常见的". is not a \n" 问题是这里唯一的问题,但实际上 OP 应该在&lt;/title&gt; 之前以及在正则表达式中覆盖填充。
    【解决方案3】:

    你应该先获取整个标题,然后使用 PHP 将其剥离,如下所示:

    <?php
    
    $raw_html=file_get_contents('http://www.allrecipes.com');
    if (empty($raw_html)) {
        throw new \RuntimeException('Fetch empty');
    }
    
    $matches=array();
    if (preg_match('/<title>(.*)<\/title>/s', $raw_html, $matches) === false) {
        throw new \RuntimeException('Regex error');
    }
    
    $title=trim($matches[1]);
    
    // you should strip your title here
    echo $title;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 2011-05-18
      相关资源
      最近更新 更多