PHP:preg_match_all来自文字

时间:2018-02-19 16:26:29

标签: php regex preg-match preg-match-all

我希望从文本youtube中提取url字符串,如https://www.youtube.com/watch?time_continue=218&v=0EB7zh_7UE4和视频ID,如0EB7zh_7UE4,这样我就可以根据视频ID在字符串后面插入文本。这是我的示例文本:

This is an example page will show up https://www.youtube.com/watch?time_continue=218&v=0EB7zh_7UE4 Bike https://www.youtube.com/watch?v=0EB7zh_7UE4&feature=youtu.be&app=desktop messenger by day, aspiring actor by night, and this is my website. I live in https://youtu.be/1EB7zh_7UE4 Los Angeles, have a great dog named Jack, and I https://www.youtube.com/watch?v=0EB7zh_7UE4&feature=youtu.be like piña coladasdoohickeys https://www.youtube.com/watch?v=4EB7zh_7UE4 you should go to <a href="http://example.com/wp-admin/">your dashboard</a> to delete this page and create new pages for your content. Have fun!

https://www.youtube.com/watch?v=0EB7zh_7UE4

more

https://www.youtube.com/watch?v=2EB7zh_7UE4&feature=youtu.be

That\'s all..

这是我到目前为止的正则表达式,但错误如下:

  • 它在链接字符串结尾之前添加(here)字符串(在中间)。一世 想在最后添加(here) Youtube url link string

  • 它返回多个here注入

参见代码:

function regex($sample_text) {
    if (preg_match_all('#(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\-nocookie\.com\/embed\/|youtube\.com\/(?:embed\/|v\/|e\/|\?v=|shared\?ci=|watch\?v=|watch\?.+&v=))([-_A-Za-z0-9]{10}[AEIMQUYcgkosw048])(.*?)\b#s', $sample_text, $matches, PREG_SET_ORDER)) {
        print_r($matches);
        foreach ($matches as $match) {
            $add = ' (here)';
            $processed_text = str_replace($match[0], $match[0] . $add, $sample_text);
        }
    }
    return $processed_text;
}
echo regex($sample_test);

我错在哪里?

注意:问题+示例文本已更新。

5 个答案:

答案 0 :(得分:1)

要扩展我的评论,您每次都会使用原始字符串$ sample_text替换结果文本。这是一个简单的修复,只需在开始时初始化$ processed_text,然后继续处理。

function regex($sample_text) {
    $processed_text = $sample_text;
    if (preg_match_all('#(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\-nocookie\.com\/embed\/|youtube\.com\/(?:embed\/|v\/|e\/|\?v=|shared\?ci=|watch\?v=|watch\?.+&v=))([-_A-Za-z0-9]{10}[AEIMQUYcgkosw048])(.*?)\b#s', $sample_text, $matches, PREG_SET_ORDER)) {
        print_r($matches);
        foreach ($matches as $match) {
            $add = ' (here)';
            $processed_text = str_replace($match[0], $match[0] . $add, $processed_text);
        }
    }
    return $processed_text;
}
echo regex($sample_test);

您的正则表达式也与URL的末尾不匹配。出于您提供的示例文本的目的,您可以匹配任何非空白的内容:

'#(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\-nocookie\.com\/embed\/|youtube\.com\/(?:embed\/|v\/|e\/|\?v=|shared\?ci=|watch\?v=|watch\?.+&v=))([-_A-Za-z0-9]{10}[AEIMQUYcgkosw048])\S*#s'

但是,这与".等字符不匹配,但您可以将其作为|添加到组中。你似乎很好地掌握了正则表达式,所以我假设你可以解决这个问题 - 如果没有,请评论,我会更新我的答案。

为了完整起见,我已将完整的代码包含在我的正则表达式中:

function regex($sample_text) {
    $processed_text = $sample_text;
    if (preg_match_all('#(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\-nocookie\.com\/embed\/|youtube\.com\/(?:embed\/|v\/|e\/|\?v=|shared\?ci=|watch\?v=|watch\?.+&v=))([-_A-Za-z0-9]{10}[AEIMQUYcgkosw048])\S*#s', $sample_text, $matches, PREG_SET_ORDER)) {
        print_r($matches);
        foreach ($matches as $match) {
            $add = ' (here)';
            $processed_text = str_replace($match[0], $match[0] . $add, $processed_text);
        }
    }
    return $processed_text;
}
echo regex($sample_test);

答案 1 :(得分:1)

<?php

$str = 'This is an example page will show up https://www.youtube.com/watch?time_continue=218&v=0EB7zh_7UE4 Bike https://www.youtube.com/watch?v=1EB7zh_7UE4&feature=youtu.be&app=desktop messenger by day, aspiring actor by night, and this is my website. I live in https://youtu.be/2EB7zh_7UE4 Los Angeles, have a great dog named Jack, and I https://www.youtube.com/watch?v=3EB7zh_7UE4&feature=youtu.be like piña coladasdoohickeys https://www.youtube.com/watch?v=4EB7zh_7UE4 you should go to <a href="http://example.com/wp-admin/">your dashboard</a> to delete this page and create new pages for your content. Have fun!

https://www.youtube.com/watch?v=5EB7zh_7UE4

more

https://www.youtube.com/watch?v=6EB7zh_7UE4&feature=youtu.be

That\'s all.';

preg_match_all('#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $str, $match);

// youtube vid ID array placeholder
$youtubeVids = array();

// Going through each URL and retrieving the video ID
foreach($match[0] as $url)
{
    // Parsing the URL
    $url = parse_url($url);

    // Retrieving the query if they exist
    if(isset($url['query']))
    {
        parse_str($url['query'], $yt_vid);
    }

    // Checking if we have the query parts
    if(isset($yt_vid['v']))
    {
        // Adding the vid ID to the vid ID list
        $youtubeVids[] = $yt_vid['v'];
    }
    else
    {
        // No queries, checking if we are checking a youtube vid (maybe regex better?)
        if(stripos($url['host'], 'youtu') !== false)
        {
            // Adding the ID to ID list (This is mainly for links like youtube.com/6EB7zh_7UE4 or youtu.be/6EB7zh_7UE4)
            $youtubeVids[] = substr($url['path'], 1);
        }
    }

    // Unsetting so it won't be set in the next loop
    unset($yt_vid);
}

print_r($youtubeVids);
?>

输出

Array
(
    [0] => 0EB7zh_7UE4
    [1] => 1EB7zh_7UE4
    [2] => 2EB7zh_7UE4
    [3] => 3EB7zh_7UE4
    [4] => 4EB7zh_7UE4
    [5] => 5EB7zh_7UE4
    [6] => 6EB7zh_7UE4
)

我在网上找到了以下解决方案。

preg_match_all('/(?:youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})\W/', $str, $match);
print_r($match);

答案 2 :(得分:0)

您可以使用

https?://\S+?\Qyoutube.com\E\S+?v=\K[^&\s]+

请参阅a demo on regex101.com

答案 3 :(得分:0)

仅仅是为了记录,我最终得到了基于this的“简单”功能:

function filter($content) {
return preg_replace_callback('#(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\-nocookie\.com\/embed\/|youtube\.com\/(?:embed\/|v\/|e\/|\?v=|shared\?ci=|watch\?v=|watch\?.+&v=))([-_A-Za-z0-9]{10}[AEIMQUYcgkosw048])\S*#s', function($match) {
    return sprintf('%s my replace with 2nd parameter found %s', $match[0], $match[1]);
}, $content);    
}

答案 4 :(得分:0)

这就是为我工作的东西:

function FindYouTubeId($url)
{
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
$youtube_id = $match[1];
return $youtube_id;
}