使用正则表达式或不使用正则表达式提取YouTube视频ID

5
请告诉我如何在不使用正则表达式的情况下获取YouTube ID?
使用上述方法无法获取以下URL中的ID,没有效果

http://www.youtube.com/e/dQw4w9WgXcQ

http://www.youtube.com/watch?feature=player_embedded&v=dQw4w9WgXcQ

public static String extractYTId(String youtubeUrl) {
    String video_id = "";

    try {
        if(youtubeUrl != null && youtubeUrl.trim().length() > 0 && youtubeUrl.startsWith("http")) {
            String expression = "^.*((youtu.be" + "\\/)" + "|(v\\/)|(\\/u\\/w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#\\&\\?]*).*"; // var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
            //String expression = "^.*(?:youtu.be\\/|v\\/|e\\/|u\\/\\w+\\/|embed\\/|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;
            }
        }
    } catch(Exception e) {
        Log.e("YoutubeActivity", "extractYTId " + e.getMessage());
    }

    return video_id;
}

其他链接正常工作。

http://www.youtube.com/v/0zM3nApSvMg?fs=1&hl=en_US&rel=0

​​http://www.youtube.com/embed/0zM3nApSvMg?rel=0

http://www.youtube.com/watch?v=0zM3nApSvMg&feature=feedrec_grec_index

http://www.youtube.com/watch?v=0zM3nApSvMg

http://youtu.be/0zM3nApSvMg

http://www.youtube.com/watch?v=0zM3nApSvMg#t=0m10s

http://youtu.be/dQw4w9WgXcQ

http://www.youtube.com/embed/dQw4w9WgXcQ

http://www.youtube.com/v/dQw4w9WgXcQ

http://www.youtube.com/watch?v=dQw4w9WgXcQ

​​​​http://www.youtube-nocookie.com/v/6L3ZvIMwZFM?version=3&hl=en_US&rel=0

3个回答

4
你可以使用以下正则表达式。

^(?:(?:https?:\/\/)?(?:www\.)?)?(youtube(?:-nocookie)?\.com|youtu\.be)\/.*?(?:embed|e|v|watch\?.*?v=)?\/?([a-z0-9]+)

正则表达式分解:

  1. ^: 行首 锚点
  2. (?:(?:https?:\/\/)?(?:www\.)?)?:
    • (?:https?:\/\/)?: 匹配可选的 http://https://
    • (?:www\.)?)?: 匹配零次或一次的 www.
  3. (youtube(?:-nocookie)?\.com|youtu\.be)\/: 匹配
    • youtube.comyoutube-nocookie.comyoutu.be 后跟 /
  4. .*?: 惰性匹配。匹配到下一个符合条件的模式为止。
  5. (?:embed|e|v|watch\?.*?v=)?\/?:
    • (?:embed|e|v|watch\?.*?v=)?: 匹配 embedev 或从 watch?v= 或不匹配
    • \/?: 匹配零次或一次的 /
  6. ([a-z0-9]+): 匹配一个或多个字母数字字符并将其添加到捕获组中。

演示使用JavaScript

var regex = /^(?:(?:https?:\/\/)?(?:www\.)?)?(youtube(?:-nocookie)?\.com|youtu\.be)\/.*?(?:embed|e|v|watch\?.*?v=)?\/?([a-z0-9]+)/i;

// An array of all the youtube URLs
var youtubeLinks = [
    'http://www.youtube.com/e/dQw4w9WgXcQ',
    'http://www.youtube.com/watch?feature=player_embedded&v=dQw4w9WgXcQ',
    'http://www.youtube.com/v/0zM3nApSvMg?fs=1&hl=en_US&rel=0',
    'http://www.youtube.com/embed/0zM3nApSvMg?rel=0',
    'http://www.youtube.com/watch?v=0zM3nApSvMg&feature=feedrec_grec_index',
    'http://www.youtube.com/watch?v=0zM3nApSvMg',
    'http://youtu.be/0zM3nApSvMg',
    'http://www.youtube.com/watch?v=0zM3nApSvMg#t=0m10s',
    'http://youtu.be/dQw4w9WgXcQ',
    'http://www.youtube.com/embed/dQw4w9WgXcQ',
    'http://www.youtube.com/v/dQw4w9WgXcQ',
    'http://www.youtube.com/watch?v=dQw4w9WgXcQ',
    'http://www.youtube-nocookie.com/v/6L3ZvIMwZFM?version=3&hl=en_US&rel=0'
];

// An object to store the results
var youtubeIds = {};

// Iterate over the youtube URLs
youtubeLinks.forEach(function(url) {
    // Get the value of second captured group to extract youtube ID
    var id = "<span class='youtubeId'>" + (url.match(regex) || [0, 0, 'No ID present'])[2] + "</span>";

    // Add the URL and the extracted ID in the result object
    youtubeIds[url] = id;
});

// Log the object in the browser console
console.log(youtubeIds);

// To show the result on the page
document.getElementById('output').innerHTML = JSON.stringify(youtubeIds, 0, 4);
.youtubeId {
    color: green;
    font-weight: bold;
}
<pre id="output"></pre>

RegEx Visualization Diagram


@Piraba 我认为在将正则表达式作为字符串添加时,您需要将反斜杠加倍。 - Tushar
我添加了反斜杠 String expression = "/^(?:(?:https?:\\/\\/)?(?:www\\.)?)?(youtube(?:-nocookie)?\\.com|youtu\\.be)\\/.*?(?:embed|e|v|watch\\?.*?v=)?\\/?([a-z0-9]+)/i";。没有起作用。 - Piraba
1
@Piraba 你需要使用 if(matcher.find()) 而不是 if(matcher.matches()) 并打印第二组。示例:if (matcher.find()) { video_id = matcher.group(2); } - Tunaki
@Tushar - 底部的“流程图”看起来是生成的...是怎么生成的?在哪里生成的?!? - T4NK3R
@T4NK3R regexper.com 是一个例子。以上是由Atom编辑器与regex-railroad-diagram包生成的。 - Tushar
显示剩余2条评论

1

您的正则表达式是针对youtu.be域名设计的,当然不能与youtube.com一起使用。

  1. 从您的URL字符串构建java.net.URL(https://docs.oracle.com/javase/7/docs/api/java/net/URL.html
  2. 使用URL#getQuery()获取查询部分
  3. 检查将URI字符串解析为名称-值集合以将查询部分解码为名称-值映射,并获取名称为“v”的值
  4. 如果没有“query”部分(例如http://www.youtube.com/e/dQw4w9WgXcQ),则使用URL#getPath()(它将给出/e/dQw4w9WgXcQ)并从中解析您的视频ID,例如跳过前3个字符:url.getPath().substring(3)

更新。为什么不使用正则表达式?因为标准的JDK URL解析器更加健壮。它经过整个Java社区的测试,而基于RegExp重新发明轮子只被你自己的代码测试。


这不是他问题的答案。 - XsiSecOfficial
他询问如何从字符串中获取视频ID(使用或不使用正则表达式),我给出了一个建议。你为什么认为这不是一个答案? - Kirill Gamazkov
实际上,这是一个非常优雅的解决方案,因为它意识到所有的URL都可以通过分析查询参数或路径参数进行编排。对我来说完美地运作。 - Mardann

0
我喜欢使用这个函数来处理所有的YouTube视频ID。我通过URL传递参数,并仅返回ID。请查看下面的fiddle示例。
 var ytSrc = function( url ){
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
    var match = url.match(regExp);
    if (match&&match[7].length==11){
        return match[7];
    }else{
     alert("Url incorrecta");
    }

}

https://jsfiddle.net/keinchy/tL4thwd7/1/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接