过滤来自内容的youtube链接与Regex

时间:2013-10-01 21:22:02

标签: php regex youtube

我有一个人们发布更新的输入区域。 所以我想过滤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取代<a>#hash</a> 你在社交媒体上看到的主题标签。

我希望自己的功能是将youtube链接转换为<a>ID</a>(基本上)

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

我想它不起作用,因为我没想出第二个$模式。其他节目就在那里。

4 个答案:

答案 0 :(得分:1)

根本不要使用正则表达式,请使用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 :)
}

答案 1 :(得分: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 :(得分:1)

尝试使用带有文本的正则表来匹配URL时的问题是,您无法知道URL何时结束。

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

如果您假设yutube网址不能包含空格(在网址的给定位置/索引之后),您可以将正则表达式的结尾更改为(?:[^\s]+)?(除了空格以外),您可以在集合中添加其他字符以定义网址的结尾,例如,如果网址不得包含,,则执行(?:[^\s,]+)?,依此类推。

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

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

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

NB。我没有分析你的正则表达式的所有逻辑,所以我的评论只值得你的正则表达式的开头和结尾。

答案 3 :(得分:0)

尝试使用网址:

导致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格式的相同步骤。