Php 使用正则表达式从内容中筛选youtube链接

Php 使用正则表达式从内容中筛选youtube链接,php,regex,youtube,Php,Regex,Youtube,我有一个输入区,人们可以在这里发布更新。 所以我想过滤youtube链接,修改它们并在最后附加它们 此内容不是html,它甚至没有或,它只是纯字符串 这是我从程序的不同部分得到的代码 这应该做的是,获取所有匹配项,并用html替换它们 function aKaFilter( $content ) { global $bp; $pattern2 = '#^(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:[^/]+/

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

此内容不是html,它甚至没有

,它只是纯字符串

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

这应该做的是,获取所有匹配项,并用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;
}
函数过滤器($content){
全球$bp;
$pattern2='#^(?:https?:/)?(?:www\)(?:youtube(?:nocookie)?\.com/(?:[^/]+/.+/。+/)(?:v | e(?:mbed)/。.[?&]v=)| youtu\.be/)([^和?/]{11})(?:.+)$#;
preg_match_all($pattern2,$content,$youtubes);
如果($youtubes){
/*确保每个视频只有一个实例*/
if(!$youtubes=array_unique($youtubes[1]))
返回$content;
//但我们需要注意编辑,如果html链接中已经包含了内容,那么在编辑之前检查空格或单词边界
foreach((数组)$youtube作为$youtube){
$pattern=“NEW”。$youtube。“匹配此链接的模式”;
$content=preg_replace($pattern,'title',$content);
}
}
返回$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;
}
function-etivite\u-bp\u-activity\u-hashtags\u-filter($content){
全球$bp;
//我们在这里干什么?-和atme提到的一样
//$pattern='/[#]([_0-9a-zA-Z-]+)/';
$pattern='/(?)?
它所做的是,它使用textarea,而不是hash,它替换为
#hash
就像你在社交媒体中看到的那样

我想让我的函数做的是获取youtube链接并将其转换为
ID
(基本上)

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


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

根本不用正则表达式,用它

例如:

$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 :)
}

完全不要使用正则表达式,请使用

例如:

$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()?在您的情况下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;
}
函数过滤器($content){
全球$bp;
$pattern2='#^(?:https?:/)?(?:www\)(?:youtube(?:nocookie)?\.com/(?:[^/]+/.+/。+/)(?:v | e(?:mbed)/。.[?&]v=)| youtu\.be/)([^和?/]{11})(?:.+)$#;
preg_match_all($pattern2,$content,$youtubes);
/*确保每个视频只有一个实例*/
$youtubes=array_unique($youtubes[1]);
如果($youtubes){
//但我们需要注意编辑,如果html链接中已经包含了内容,那么在编辑之前检查空格或单词边界
foreach($youtube[0]作为$youtube){
$content=str_replace($youtube,'title',$content);
}
}
返回$content;
}

为什么需要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;
}
函数过滤器($content){
全球$bp;
$pattern2='#^(?:https?:/)?(?:www\)(?:youtube(?:nocookie)?\.com/(?:[^/]+/.+/。+/)(?:v | e(?:mbed)/。.[?&]v=)| youtu\.be/)([^和?/]{11})(?:.+)$#;
preg_match_all($pattern2,$content,$youtubes);
/*确保每个视频只有一个实例*/
$youtubes=array_unique($youtubes[1]);
如果($youtubes){
//但我们需要注意编辑,如果html链接中已经包含了内容,那么在编辑之前检查空格或单词边界
foreach($youtube[0]作为$youtube){
$content=str_replace($youtube,'title',$content);
}
}
返回$content;
}

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

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

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

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

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

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


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

当试图使用带有文本的正则表达式匹配URL时,问题是你不知道URL何时结束

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

如果假设yutube URL不能包含空格(在URL的给定位置/索引之后),可以通过
(?:[^\s]+)?
(除空格外的所有字符)更改正则表达式的结尾,您可以向集合中添加其他字符以定义y的结尾