【问题标题】:filter youtube links from content with Regex使用正则表达式从内容中过滤 youtube 链接
【发布时间】:2013-10-01 21:22:02
【问题描述】:

我有一个人们发布更新的输入区域。 所以我想过滤 youtube 链接,修改它们并在最后附加它们。

这个内容不是html,它甚至没有<br><p>,它只是一个纯字符串。

这是我从程序不同部分得到的代码。

这应该做的是,获取所有匹配项,并用 html 替换它们。

function aKaFilter( $content ) {
    global $bp;

    $pattern2 = '#^(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})(?:.+)?$#x';
    preg_match_all( $pattern2, $content, $youtubes );
    if ( $youtubes ) {
        /* Make sure there's only one instance of each video */
        if ( !$youtubes = array_unique( $youtubes[1] ) )
            return $content;

        //but we need to watch for edits and if something was already wrapped in html link - thus check for space or word boundary prior
        foreach( (array)$youtubes as $youtube ) {
            $pattern = "NEW". $youtube ."PATTERN TO MATCH THIS LINK";
            $content = preg_replace( $pattern, '<span class="video youtube" data-trigger="'.$youtube.'"><img src="http://img.youtube.com/vi/'.$youtube.'/0.jpg"><span class="icon-stack"><i class="icon-circle icon-stack-base"></i><i class="icon-youtube-play"></i></span><span>title</span></span>', $content );
        }
    }

    return $content;
}

这是一个原始代码:

function etivite_bp_activity_hashtags_filter( $content ) {
global $bp;

//what are we doing here? - same at atme mentions
//$pattern = '/[#]([_0-9a-zA-Z-]+)/';
$pattern = '/(?(?<!color: )(?<!color: )[#]([_0-9a-zA-Z-]+)|(^|\s|\b)[#]([_0-9a-zA-Z-]+))/';

preg_match_all( $pattern, $content, $hashtags );
if ( $hashtags ) {
    /* Make sure there's only one instance of each tag */
    if ( !$hashtags = array_unique( $hashtags[1] ) )
        return $content;

    //but we need to watch for edits and if something was already wrapped in html link - thus check for space or word boundary prior
    foreach( (array)$hashtags as $hashtag ) {
        $pattern = "/(^|\s|\b)#". $hashtag ."($|\b)/";
        $content = preg_replace( $pattern, ' <a href="' . $bp->root_domain . "/" . $bp->activity->slug . "/". BP_ACTIVITY_HASHTAGS_SLUG ."/" . htmlspecialchars( $hashtag ) . '" rel="nofollow" class="hashtag">#'. htmlspecialchars( $hashtag ) .'</a>', $content );
    }
}

return $content;
}

它的作用是,它需要 textarea,而不是 #hash 它替换为 &lt;a&gt;#hash&lt;/a&gt; 像您在社交媒体中看到的主题标签。

我希望我的功能做的是获取 youtube 链接并将其转换为 &lt;a&gt;ID&lt;/a&gt;(基本上)

如果我只有 youtube 链接,它可以正常工作,但是当它在它之后或之前带有字符串时,它就会变得疯狂。

我猜它不起作用,因为我没有想出第二个 $pattern。在其他程序中。

【问题讨论】:

标签: php regex youtube


【解决方案1】:

为什么需要 preg_replace()? str_replace() 在您的情况下就足够了。 此外,您可能需要遍历 $youtubes[0],而不是 $youtubes。 再加上简化你的代码! ;-)

因此这应该可以工作:

function aKaFilter( $content ) {
    global $bp;

    $pattern2 = '#^(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})(?:.+)?$#x';
    preg_match_all( $pattern2, $content, $youtubes );

    /* Make sure there's only one instance of each video */
    $youtubes = array_unique( $youtubes[1] );

    if ( $youtubes ) {

        //but we need to watch for edits and if something was already wrapped in html link - thus check for space or word boundary prior
        foreach( $youtubes[0] as $youtube ) {

            $content = str_replace( $youtube, '<span class="video youtube" data-trigger="'.$youtube.'"><img src="http://img.youtube.com/vi/'.$youtube.'/0.jpg"><span class="icon-stack"><i class="icon-circle icon-stack-base"></i><i class="icon-youtube-play"></i></span><span>title</span></span>', $content );
        }
    }

    return $content;
}

【讨论】:

    【解决方案2】:

    不要为此使用正则表达式,使用parse_url

    例如:

    $parsed_url = parse_url($content);
    if (in_array($parsed_url['host'], array('www.youtube.com', 'youtube.com', 'www.youtube-nocookie.com', 'youtube-nocookie.com'))) {
        ## Now look through $parsed_url['query'] for the video ID
        ## Parsing this out is a separate question :)
    }
    

    【讨论】:

    • 实际上问题是关于不同的部分,因为解析器工作正常(除了我认为可以解决的情况,我只需要告诉表达式继续直到空格或类似的东西)问题是关于在preg_replace中使用$patter的foreach部分
    • 好的,我纠正了我的问题,写得真的很糟糕。
    【解决方案3】:

    尝试使用正则表达式与文本匹配 URL 时的问题是您无法知道 URL 何时结束。

    URL 可以包含“空格”、., 和其他字符,因此不能说 URL 在新单词开始或句子结束时结束。此外,您的正则表达式 (?:.+)? 的结尾将匹配(几乎)所有内容

    如果您假设 yutube URL 不能包含空格(在 URL 的给定位置/索引之后),您可以将正则表达式的结尾更改为 (?:[^\s]+)?(除空格外),您可以将其他字符添加到集合中以定义 URL 的结尾,例如,如果 URL 也不能包含 ,,则使用 (?:[^\s,]+)?,等等。

    然后,您在正则表达式(^$)上设置开始和结束锚点。当您的 URL 被一些文本包围时,这可能不起作用,因此您可以删除这些锚点并在正则表达式的开头添加 \b(单词边界)锚点。

    顺便说一句,您可以将(?:.+)?替换为.*,将(?:[^\s,]+)?替换为`[^\s,]*

    你现在有一个这样的正则表达式:'#\b(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/ ]{11})[^\s,]*#x'

    注意。我没有分析你的正则表达式的所有逻辑,所以我的 cmets 只对你的正则表达式的开头和结尾有价值。

    【讨论】:

    • 谢谢你,它现在真的应该有帮助,但我选择了不同的答案
    【解决方案4】:

    尝试使用网址:

    结果为 JSON 格式。 http://gdata.youtube.com/feeds/mobile/videos?alt=json&q=music&format=1,5,6

    结果为 xml 格式 http://gdata.youtube.com/feeds/mobile/videos?q=music&format=1,5,6

    那么, 对于 xml 格式 使用正则表达式 -- 标签:youtube.com,2008:视频:qycqF1CWcXg 并检索视频 ID,即本例中的“qycqF1CWcXg”

    适用于 JSON 格式的相同步骤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多