【问题标题】:Get two results without repeating preg_match and file_get_contents在不重复 preg_match 和 file_get_contents 的情况下获得两个结果
【发布时间】:2013-06-25 00:31:52
【问题描述】:

我是php新手

我需要从同一页面获得两个结果。 og:image 和 og:video

这是我当前的代码

preg_match('/property="og:video" content="(.*?)"/', file_get_contents($url), $matchesVideo);
preg_match('/property="og:image" content="(.*?)"/', file_get_contents($url), $matchesThumb);

$videoID = ($matchesVideo[1]) ? $matchesVideo[1] : false;
$videoThumb = ($matchesThumb[1]) ? $matchesThumb[1] : false;

有没有办法在不复制我的代码的情况下执行相同的操作

【问题讨论】:

  • 当然,把file_get_contents的结果赋值给一个变量。
  • 但是你必须做两次 preg_match,因为它不是同一个操作。但是是的,$content = file_get_contents($url); 会节省很多时间

标签: php preg-match file-get-contents


【解决方案1】:

将文件内容保存到变量中,如果要运行单个正则表达式,可以选择:

$file = file_get_contents($url);
preg_match_all('/property="og:(?P<type>video|image)" content="(?P<content>.*?)"/', $file, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
    $match['type'] ...
    $match['content'] ...
}

正如@hakre 指出的那样,不需要第一个括号对:

第一个括号对使用不捕获修饰符?:,它会导致匹配但不存储

捕获组使用命名子模式?P&lt;name&gt;,第二个捕获组建立两个单词中的任何一个都可能匹配image|video

【讨论】:

  • 第一个(不匹配的)括号对在我看来是多余的。组 0 无论如何都会匹配,子组无论如何都会匹配。它只是不需要,因此您可以专注于解释指定的子模式,而不是首先讨论不需要的不匹配组;)
  • 我不这么认为,type 不同的标签可能会匹配模式
  • 不,只能匹配整个模式。那是视频或图像,没有其他类型。组 0 是内在的,您不需要显式创建它(始终是整个模式,理想情况下使用 () 作为外括号而不是 //)。试试看。
【解决方案2】:

这两行没有问题。我要改变的是对file_get_contents($url) 的双重调用。

只需将其更改为:

$html = file_get_contents($url);
preg_match('/property="og:video" content="(.*?)"/', $html, $matchesVideo);
preg_match('/property="og:image" content="(.*?)"/', $html, $matchesThumb);

【讨论】:

    【解决方案3】:

    有没有办法在不复制我的代码的情况下执行相同的操作

    总是有两种方法可以做到这一点:

    1. 缓冲执行结果 - 而不是多次执行。
    2. 对重复进行编码 - 从代码中提取参数。

    在编程中,您通常会同时使用这两者。比如文件I/O操作的缓冲:

    $buffer = file_get_contents($url);
    

    为了匹配,你对重复进行编码:

    $match = function ($what) use ($buffer) {
        $pattern = sprintf('/property="og:%s" content="(.*?)"/', $what);
        $result  = preg_match($pattern, $buffer, $matches);
        return $result ? $matches[1] : NULL;
    }
    
    $match('video');
    $match('image');
    

    这只是为了说明我的意思。这取决于您想要执行此操作的程度,例如后者允许将匹配替换为不同的实现,例如使用 HTML 解析器,但您可能会发现此时它的代码太多,无法满足您的需求,只能使用缓冲。

    例如以下内容也适用:

    $buffer = file_get_contents($url);
    $mask   = '/property="og:%s" content="(.*?)"/';
    preg_match(sprintf($mask, 'video'), $buffer, $matchesVideo);
    preg_match(sprintf($mask, 'image'), $buffer, $matchesThumb);
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      • 2012-10-11
      • 1970-01-01
      • 2023-03-25
      相关资源
      最近更新 更多