使用RegEx从字符串获取YouTube视频url或YouTube视频ID

2024-10-01 02:18:26 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我已经在这上面耽搁了一个小时左右,我就是不能让它发挥作用。到目前为止,我一直在尝试从字符串中提取整个链接,但现在我觉得只获取视频ID可能更容易

RegEx需要从以下链接样式中获取ID/URL,无论它们在字符串中的哪个位置:

http://youtube.com/watch?v=iwGFalTRHDA
http://www.youtube.com/watch?v=iwGFalTRHDA&feature=related
https://youtube.com/iwGFalTRHDA
http://youtu.be/n17B_uFF4cA
youtube.com/iwGFalTRHDA
youtube.com/n17B_uFF4cA
http://www.youtube.com/embed/watch?feature=player_embedded&v=r5nB9u4jjy4
http://www.youtube.com/watch?v=t-ZRX8984sc
http://youtu.be/t-ZRX8984sc

到目前为止,我有一个正则表达式:

^{pr2}$

这会捕获链接,但它也会将链接分解为多个部分,并将其添加到列表中,因此,如果字符串包含单个youtube链接,则打印列表时的输出如下所示:

('https://www.youtube.com/watch?v=Idn7ODPMhFY', 'https://', 's', 'www.', 'youtube', '.com/', '.com', 'watch?v=', 'Idn7ODPMhFY', '', '')

我需要列表只包含链接本身,或只是视频id(这将是更可取的)。我真的试着自己做了一段时间,但我就是搞不懂。我想知道是否有人能为我整理正则表达式,告诉我哪里出错了,这样我以后就不会再碰到这个问题了?在


Tags: 字符串httpscomidhttp列表视频youtube
3条回答

下面是我要使用的方法,根本不需要正则表达式。在

(这相当于@Willem Van Onsem的解决方案,加上易于运行/更新的单元测试)。

from urlparse import parse_qs
from urlparse import urlparse
import re
import unittest


TEST_URLS = [
    ('iwGFalTRHDA', 'http://youtube.com/watch?v=iwGFalTRHDA'),
    ('iwGFalTRHDA', 'http://www.youtube.com/watch?v=iwGFalTRHDA&feature=related'),
    ('iwGFalTRHDA', 'https://youtube.com/iwGFalTRHDA'),
    ('n17B_uFF4cA', 'http://youtu.be/n17B_uFF4cA'),
    ('iwGFalTRHDA', 'youtube.com/iwGFalTRHDA'),
    ('n17B_uFF4cA', 'youtube.com/n17B_uFF4cA'),
    ('r5nB9u4jjy4', 'http://www.youtube.com/embed/watch?feature=player_embedded&v=r5nB9u4jjy4'),
    ('t-ZRX8984sc', 'http://www.youtube.com/watch?v=t-ZRX8984sc'),
    ('t-ZRX8984sc', 'http://youtu.be/t-ZRX8984sc'),
    (None, 'http://www.stackoverflow.com')
]

YOUTUBE_DOMAINS = [
    'youtu.be',
    'youtube.com',
]


def extract_id(url_string):
    # Make sure all URLs start with a valid scheme
    if not url_string.lower().startswith('http'):
        url_string = 'http://%s' % url_string

    url = urlparse(url_string)

    # Check host against whitelist of domains
    if url.hostname.replace('www.', '') not in YOUTUBE_DOMAINS:
        return None

    # Video ID is usually to be found in 'v' query string
    qs = parse_qs(url.query)
    if 'v' in qs:
        return qs['v'][0]

    # Otherwise fall back to path component
    return url.path.lstrip('/')


class TestExtractID(unittest.TestCase):

    def test_extract_id(self):
        for expected_id, url in TEST_URLS:
            result = extract_id(url)
            self.assertEqual(
                expected_id, result, 'Failed to extract ID from '
                'URL %r (got %r, expected %r)' % (url, result, expected_id))


if __name__ == '__main__':
    unittest.main()

与其编写一个复杂的regex,而不是在所有情况下都能正常工作,不如使用工具来分析url,比如urllib

from urllib.parse import urlparse, parse_qs

url = 'http://youtube.com/watch?v=iwGFalTRHDA'

def get_id(url):
    u_pars = urlparse(url)
    quer_v = parse_qs(u_pars.query).get('v')
    if quer_v:
        return quer_v[0]
    pth = u_pars.path.split('/')
    if pth:
        return pth[-1]

如果两次尝试都失败,此函数将返回None。在

我用示例URL进行了测试:

^{pr2}$

我真的建议@LukasGraf的评论,但是如果您真的必须使用regex,您可以检查以下内容:

(?:(?:https?\:\/\/)?(?:www\.)?(?:youtube|youtu)(?:(?:\.com|\.be)\/)(?:embed\/)?(?:watch\?)?(?:feature=player_embedded)?&?(?:v=)?([0-z]{11}|[0-z]{4}(\-|\_)[0-z]{4}|.(\-|\_)[0-z]{9}))

下面是regex101中的一个工作示例: https://regex101.com/r/5eRqn2/1

下面是python示例:

^{pr2}$

In order to not catch specific group in regex you should this: (?:...)

相关问题 更多 >