【问题标题】:PHP - preg_replace YouTube embed no matter the orderPHP - preg_replace YouTube 嵌入,无论顺序如何
【发布时间】:2019-02-25 21:40:32
【问题描述】:

我正在尝试从 YouTube 嵌入代码中捕获 3 个元素,但有时这些元素的顺序不同,或者有时嵌入代码包含更多参数。

我想找到一种方法来提取视频 ID、宽度和长度,以便为 AMP 创建 YouTube 集成。

嵌入示例:

<iframe width="560" height="315" src="https://www.youtube.com/embed/bpcNPHqs4ng" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

应该转化为:

<amp-youtube data-videoid="bpcNPHqs4ng" width="560" height="315" 
layout="responsive"></amp-youtube>

如果嵌入始终相同,则很容易解决,但有时嵌入代码从源代码开始,有时以宽度开头,......所以无论我需要捕获 ID、宽度和高度。

我可以用 PHP 中的 preg_replace 来做到这一点吗?

我试过了:

preg_replace('/<iframe width="([0-9]+)" height="([0-9]+)" src="https:\/\/www.youtube.com\/embed\/([A-Za-z0-9]+)" (.*)><\/iframe>/', '<amp-youtube data-videoid="$3" width="$1" height="$2" layout="responsive"></amp-youtube>', $article);

$article 包含使用 YouTube 嵌入的整篇文章。

如果 DOM 解析器也能做到这一点,我也可以,但我对此不太熟悉。

谢谢

【问题讨论】:

  • 您的代码似乎正确...检查3v4l.org/T7TDp
  • 我会做一个正则表达式,将所有属性以它们出现的任何顺序拉入一个 key="value" 数组中,然后使用 PHP 来构建你的新标签。虽然我确信可以构建一个可以直接产生最终结果的正则表达式,但如果改为创建一个简单的循环,复杂性将会更容易管理。
  • @SilvioQ 是的,我的代码可以工作,但有时我会以不同的顺序获得宽度、高度和源的 iframe,因此它会破坏 preg_replace。我正在寻找更不可知论的东西。

标签: php preg-replace amp-html domparser


【解决方案1】:

这是解决您的问题的DOMDocument 解决方案,使用DOMXPath 搜索具有src 属性且包含youtubeiframe 标记,然后将它们替换为相应的&lt;amp-youtube&gt; 元素:

$doc = new DOMDocument();
$doc->loadHTML($article, LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
foreach ($xpath->query("//iframe[contains(@src, 'youtube')]") as $youtube) {
    // create a new node
    $node = $doc->createElement('amp-youtube');
    // set attributes
    $node->setAttribute('data-videoid', basename(parse_url($youtube->getAttribute('src'), PHP_URL_PATH)));
    $node->setAttribute('width', $youtube->getAttribute('width'));
    $node->setAttribute('height', $youtube->getAttribute('height'));
    $node->setAttribute('layout', 'responsive');
    // and now replace the old node
    $youtube->parentNode->replaceChild($node, $youtube);
}
echo $doc->saveHTML();

输出(用于我的演示数据):

<html>
  <body>
    <div>some text</div>
    <iframe name="notyoutube" src="http://example.com"></iframe>
    <p>some more text</p> 
    <amp-youtube data-videoid="bpcNPHqs4ng" width="560" height="315" layout="responsive"></amp-youtube>
    <div>one last div</div>
  </body>
</html>

Demo on 3v4l.org

【讨论】:

  • 这是一个优雅的解决方案,它可能比 preg_replace 好得多,但我想知道如何使用它来用 amp-youtube 替换 $article 中的所有 youtube iframe。此处的代码显示了原始变量之外的最终 amp-youtube。谢谢!
  • @Laurent 请看我的编辑。这将修改输入 HTML 以将 youtube iframe 元素替换为 amp-youtube 元素。
  • 我希望我和你一样好:) 谢谢它完美地工作。对于那些感兴趣的人,我建议将警告静音,因为 domdocument 不喜欢 AMP 文档。
猜你喜欢
  • 1970-01-01
  • 2012-04-11
  • 2017-07-27
  • 2012-07-24
  • 2012-05-13
  • 2013-08-22
  • 2010-09-29
  • 2018-02-03
  • 2011-03-19
相关资源
最近更新 更多