如何使用 Java 中的正则表达式从 YouTube URL 获取视频 ID

Posted

技术标签:

【中文标题】如何使用 Java 中的正则表达式从 YouTube URL 获取视频 ID【英文标题】:How to get the video id from a YouTube URL with regex in Java 【发布时间】:2014-07-25 17:52:59 【问题描述】:

javascript 答案移植到 Java 版本 JavaScript REGEX: How do I get the YouTube video id from a URL?

【问题讨论】:

【参考方案1】:

认为这个问题不是针对 Java 的,如果您需要在 Java 中这样做,这是一种方法

public static String extractYTId(String ytUrl) 
    String vId = null;
    Pattern pattern = Pattern.compile(
                     "^https?://.*(?:youtu.be/|v/|u/\\w/|embed/|watch?v=)([^#&?]*).*$", 
                     Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(ytUrl);
    if (matcher.matches())
        vId = matcher.group(1);
    
    return vId;

适用于(也适用于https://...)等网址

http://www.youtube.com/watch?v=0zM4nApSvMg&feature=feedrec_grec_index
http://www.youtube.com/user/SomeUser#p/a/u/1/QDK8U-VIH_o
http://www.youtube.com/v/0zM4nApSvMg?fs=1&hl=en_US&rel=0
http://www.youtube.com/watch?v=0zM4nApSvMg#t=0m10s
http://www.youtube.com/embed/0zM4nApSvMg?rel=0
http://www.youtube.com/watch?v=0zM4nApSvMg
http://youtu.be/0zM4nApSvMg

【讨论】:

您不需要在 Java ore 正则表达式中转义 /# & 也不是正则表达式元字符,因此您无需转义它们。你只需要转义?,但只有在字符类[..]之外,所以这里你不需要。 我编辑了答案以删除不必要的转义和强制不区分大小写的匹配。 这个方法返回null 不适用于https://m.youtube.com/watch?feature=youtu.be&v=123 类型的链接 不适用于您列出的某些网址,也不适用于https://www.youtube.com/watch?v= 0zM4nApSvMg&feature=youtu.be【参考方案2】:

以前的答案对我不起作用..这是正确的方法。它适用于 www.youtube.com 和 youtu.be 链接。

private String getYouTubeId (String youTubeUrl) 
    String pattern = "(?<=youtu.be/|watch\\?v=|/videos/|embed\\/)[^#\\&\\?]*";
    Pattern compiledPattern = Pattern.compile(pattern);
    Matcher matcher = compiledPattern.matcher(youTubeUrl);
    if(matcher.find())
        return matcher.group();
     else 
        return "error";  
    

【讨论】:

Gubatron 的回答对我不起作用,但对我有用。 (? 失败:m.youtube.com/watch?feature=youtu.be&v=faAVAai7szM【参考方案3】:

我知道这个话题很老,但我有更多的案例来获取 Youtube id,这是我的正则表达式

http(?:s)?:\/\/(?:m.)?(?:www\.)?youtu(?:\.be\/|be\.com\/(?:watch\?(?:feature=youtu.be\&)?v=|v\/|embed\/|user\/(?:[\w#]+\/)+))([^&#?\n]+)

这将适用于

http://www.youtube.com/watch?v=0zM4nApSvMg&feature=feedrec_grec_index
http://www.youtube.com/user/SomeUser#p/a/u/1/QDK8U-VIH_o
http://www.youtube.com/v/0zM4nApSvMg?fs=1&amp;hl=en_US&amp;rel=0
http://www.youtube.com/watch?v=0zM4nApSvMg#t=0m10s
http://www.youtube.com/embed/0zM4nApSvMg?rel=0
http://www.youtube.com/watch?v=0zM4nApSvMg
http://youtu.be/0zM4nApSvMg
https://www.youtube.com/watch?v=nBuae6ilH24
https://www.youtube.com/watch?v=pJegNopBLL8
http://www.youtube.com/watch?v=0zM4nApSvMg#t=0m10s
https://www.youtube.com/watch?v=0zM4nApSvMg&feature=youtu.be
https://www.youtube.com/watch?v=_5BTo2oZ0SE
https://m.youtube.com/watch?feature=youtu.be&v=_5BTo2oZ0SE
https://m.youtube.com/watch?v=_5BTo2oZ0SE
https://www.youtube.com/watch?feature=youtu.be&v=_5BTo2oZ0SE&app=desktop
https://www.youtube.com/watch?v=nBuae6ilH24
https://www.youtube.com/watch?v=eLlxrBmD3H4

注意:使用正则表达式匹配组(1)获取ID

public static String getVideoId(@NonNull String videoUrl) 
    String videoId = "";
    String regex = "http(?:s)?:\\/\\/(?:m.)?(?:www\\.)?youtu(?:\\.be\\/|be\\.com\\/(?:watch\\?(?:feature=youtu.be\\&)?v=|v\\/|embed\\/|user\\/(?:[\\w#]+\\/)+))([^&#?\\n]+)";
    Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(url);
    if(matcher.find())
        videoId = matcher.group(1);
    
    return videoId;

【讨论】:

@Devon 这是一个字符串模式,您可以使用任何支持此模式的语言,例如 Java、C#... 最适合那些寻找正则表达式的人,但不适合那些寻找完整代码的人。【参考方案4】:

对我来说,对于您发布的示例链接,这个正则表达式看起来更精确(将 ID 捕获到第 1 组):

https?://(?:www\.)?youtu(?:\.be/|be\.com/(?:watch\?v=|v/|embed/|user/(?:[\w#]+/)+))([^&#?\n]+)

在demo 上,查看右下方窗格中的捕获组。但是,对于第二场比赛,不能完全确定这是一个正确的 ID,因为它看起来与其他样本不同——如果需要,可以进行调整。

在代码中,类似于:

Pattern regex = Pattern.compile("http://(?:www\\.)?youtu(?:\\.be/|be\\.com/(?:watch\\?v=|v/|embed/|user/(?:[\\w#]+/)+))([^&#?\n]+)");
    Matcher regexMatcher = regex.matcher(subjectString);
    if (regexMatcher.find()) 
        VideoID = regexMatcher.group(1);
     

【讨论】:

修复了你的 https http(?:s)?://(?:www\.)?youtu(?:\.be/|be\.com/(?:watch\?v=|v/|embed/|user/(?:[\w#]+/)+))([^&amp;#?\n]+)【参考方案5】:
private fun extractVideoId(ytUrl: String?): String? 
        var videoId: String? = null
        val regex =
            "^((?:https?:)?//)?((?:www|m)\\.)?((?:youtube\\.com|youtu.be|youtube-nocookie.com))(/(?:[\\w\\-]+\\?v=|feature=|watch\\?|e/|embed/|v/)?)([\\w\\-]+)(\\S+)?\$"
        val pattern: Pattern = Pattern.compile(
            regex ,
            Pattern.CASE_INSENSITIVE
        )
        val matcher: Matcher = pattern.matcher(ytUrl)
        if (matcher.matches()) 
            videoId = matcher.group(5)
        
        return videoId

上面带有正则表达式的函数可以从中提取视频ID

https://www.youtube.com/watch?v=DFYRQ_zQ-gk&feature=featured
https://www.youtube.com/watch?v=DFYRQ_zQ-gk
http://www.youtube.com/watch?v=DFYRQ_zQ-gk
http://www.youtube.com/watch?v=DFYRQ_zQ-gk
http://www.youtube.com/watch?v=DFYRQ_zQ-gk
https://youtube.com/watch?v=DFYRQ_zQ-gk
http://youtube.com/watch?v=DFYRQ_zQ-gk
https://youtube.com/watch?v=DFYRQ_zQ-gk
http://youtube.com/watch?v=DFYRQ_zQ-gk
https://m.youtube.com/watch?v=DFYRQ_zQ-gk
http://m.youtube.com/watch?v=DFYRQ_zQ-gk
http://m.youtube.com/watch?v=DFYRQ_zQ-gk
http://m.youtube.com/watch?v=DFYRQ_zQ-gk
https://www.youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US
http://www.youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US
http://www.youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US
http://www.youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US
http://youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US
https://www.youtube.com/embed/DFYRQ_zQ-gk?autoplay=1
https://www.youtube.com/embed/DFYRQ_zQ-gk
http://www.youtube.com/embed/DFYRQ_zQ-gk
http://www.youtube.com/embed/DFYRQ_zQ-gk
http://www.youtube.com/embed/DFYRQ_zQ-gk
https://youtube.com/embed/DFYRQ_zQ-gk
http://youtube.com/embed/DFYRQ_zQ-gk
http://youtube.com/embed/DFYRQ_zQ-gk
https://youtube.com/embed/DFYRQ_zQ-gk
https://youtu.be/DFYRQ_zQ-gk?t=120
https://youtu.be/DFYRQ_zQ-gk
http://youtu.be/DFYRQ_zQ-gk
http://youtu.be/DFYRQ_zQ-gk
http://youtu.be/DFYRQ_zQ-gk
https://www.youtube.com/HamdiKickProduction?v=DFYRQ_zQ-gk
https://www.youtube.com/watch?v=wz4MLJBdSpw&t=67s
http://www.youtube.com/watch?v=dQw4w9WgXcQ&a=GxdCwVVULXctT2lYDEPllDR0LRTutYfW
http://www.youtube.com/embed/dQw4w9WgXcQ
http://www.youtube.com/watch?v=dQw4w9WgXcQ
https://www.youtube.com/watch?v=EL-UCUAt8DQ
http://www.youtube.com/watch?v=dQw4w9WgXcQ 
http://youtu.be/dQw4w9WgXcQ 
http://www.youtube.com/v/dQw4w9WgXcQ 
http://www.youtube.com/e/dQw4w9WgXcQ
http://www.youtube.com/watch?feature=player_embedded&v=dQw4w9WgXcQ

【讨论】:

OP 要求 JAVA 解决方案【参考方案6】:

尝试了其他的,但在我的情况下失败了 - 调整正则表达式以适合我的网址

public static String extractYoutubeVideoId(String ytUrl) 

        String vId = null;

        String pattern = "(?<=watch\\?v=|/videos/|embed\\/)[^#\\&\\?]*";

        Pattern compiledPattern = Pattern.compile(pattern);
        Matcher matcher = compiledPattern.matcher(ytUrl);

        if(matcher.find())
            vId= matcher.group();
        
        return vId;
    

这个适用于以下网址

http://www.youtube.com/embed/Woq5iX9XQhA?html5=1

http://www.youtube.com/watch?v=384IUU43bfQ

http://gdata.youtube.com/feeds/api/videos/xTmi7zzUa-M&whatever

https://www.youtube.com/watch?v=C7RVaSEMXNk

希望它会帮助一些人。谢谢

【讨论】:

【参考方案7】:

使用 Tấn Nguyên 的正则表达式:

public String getVideoIdFromYoutubeUrl(String url)
    String videoId = null;
    String regex = "http(?:s)?:\\/\\/(?:m.)?(?:www\\.)?youtu(?:\\.be\\/|be\\.com\\/(?:watch\\?(?:feature=youtu.be\\&)?v=|v\\/|embed\\/|user\\/(?:[\\w#]+\\/)+))([^&#?\\n]+)";
    Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(url);
    if(matcher.find())
        videoId = matcher.group(1);
    
    return videoId;

感谢 Tấn Nguyên。

【讨论】:

【参考方案8】:

这对我有用,而且很简单..

public static String getVideoId(@NonNull String videoUrl) 
    String reg = "(?:youtube(?:-nocookie)?\\.com\\/(?:[^\\/\\n\\s]+\\/\\S+\\/|(?:v|e(?:mbed)?)\\/|\\S*?[?&]v=)|youtu\\.be\\/)([a-zA-Z0-9_-]11)";
    Pattern pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(videoUrl);

    if (matcher.find())
        return matcher.group(1);
    return null;

【讨论】:

【参考方案9】:

只需在下面的函数中传递 youtube 链接,它将检测所有类型的 youtube url

    public static String getYoutubeID(String youtubeUrl) 

    if (TextUtils.isEmpty(youtubeUrl)) 
        return "";
    
    String video_id = "";

    String expression = "^.*((youtu.be" + "\\/)" + "|(v\\/)|(\\/u\\/w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#\\&\\?]*).*"; // var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
    CharSequence input = youtubeUrl;
    Pattern pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(input);
    if (matcher.matches()) 
        String groupIndex1 = matcher.group(7);
        if (groupIndex1 != null && groupIndex1.length() == 11)
            video_id = groupIndex1;
    
    if (TextUtils.isEmpty(video_id)) 
        if (youtubeUrl.contains("youtu.be/")  ) 
            String spl = youtubeUrl.split("youtu.be/")[1];
            if (spl.contains("\\?")) 
                video_id = spl.split("\\?")[0];
            else 
                video_id =spl;
            

        
    

    return video_id;

【讨论】:

【参考方案10】:

建议结合几种方法,以涵盖尽可能多的格式。

String ID1 = getYoutubeID1(url); regex 1
String ID2 = getYoutubeID2(url); regex 2
String ID3 = getYoutubeID3(url); regex 3

然后,使用 if/switch 语句选择一个不为空且有效的值。

【讨论】:

【参考方案11】:

我确实尝试了以上所有方法,但有时会奏效,有时会失败 我发现这可能会有所帮助-在此site

private final static String expression = "(?<=watch\\?v=|/videos/|embed\\/|youtu.be\\/|\\/v\\/|\\/e\\/|watch\\?v%3D|watch\\?feature=player_embedded&v=|%2Fvideos%2F|embed%\u200C\u200B2F|youtu.be%2F|%2Fv%2F)[^#\\&\\?\\n]*";
public static String getVideoId(String videoUrl) 
        if (videoUrl == null || videoUrl.trim().length() <= 0)
            return null;
    
        Pattern pattern = Pattern.compile(expression);
        Matcher matcher = pattern.matcher(videoUrl);
        try 
            if (matcher.find())
                return matcher.group();
         catch (ArrayIndexOutOfBoundsException ex) 
        ex.printStackTrace();
        
        return null;
    

他说

这将适用于直接或共享 URL 的两种 youtube 视频 URL。

直接网址:https://www.youtube.com/watch?v=XXXXXXXXXXX

分享网址:https://youtu.be/XXXXXXXXXXX

【讨论】:

【参考方案12】:

没有regex

String url - "https://www.youtube.com/watch?v=BYrumLBuzHk"
String video_id = url.replace("https://www.youtube.com/watch?v=", "")

所以现在您在字符串 video_id 中有一个视频 ID。

【讨论】:

【参考方案13】:

这与您问题中发布的链接非常相​​似。

String url = "https://www.youtube.com/watch?v=wZZ7oFKsKzY";
if(url.indexOf("v=") == -1) //there's no video id
    return "";
String id  = url.split("v=")[1]; //everything before the first 'v=' will be the first element, i.e. [0]
int end_of_id = id_to_end.indexOf("&"); //if there are other parameters in the url, get only the id's value
if(end_index != -1)
     id = url.substring(0, end_of_id);
return id;

【讨论】:

以上是关于如何使用 Java 中的正则表达式从 YouTube URL 获取视频 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何否定Java中的任何正则表达式

如何在 Java 中的 String.contains() 方法中使用正则表达式

java - 如何使用正则表达式作为过程中的参数通过java执行sql过程?

正则表达式中的插入操作

如何使用正则表达式从 PySpark databricks 笔记本中的文件中解析表名

Java中正则表达式如何实现从右往左匹配?