我正在制作正则表达式,因此我可以在用户发布的HTML文本中找到youtube链接(可以是多个)。
目前,我正在使用以下正则表达式将“http://www.youtube.com/watch?v=-JyZLS2IhkQ”更改为显示相应的YouTube视频:
return re.compile('(http(s|):\/\/|)(www.|)youtube.(com|nl)\/watch\?v\=([a-zA-Z0-9-_=]+)').sub(tag, value)
(变量'tag'有点html所以视频有效,'值'是用户帖子)
现在这可行..直到网址如下:
的 'http://www.youtube.com/watch V = -JyZLS2IhkQ&安培;特征...'
现在我希望你们能帮助我找出如何匹配'& feature ...'部分,以便它消失。
示例HTML:
No replies to this post..
Youtube vid:
http://www.youtube.com/watch?v=-JyZLS2IhkQ
More blabla
感谢您的想法,非常感谢
的Stefan
答案 0 :(得分:6)
这是我如何解决它:
def youtube_url_validation(url):
youtube_regex = (
r'(https?://)?(www\.)?'
'(youtube|youtu|youtube-nocookie)\.(com|be)/'
'(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
youtube_regex_match = re.match(youtube_regex, url)
if youtube_regex_match:
return youtube_regex_match.group(6)
return youtube_regex_match
测试:
youtube_urls_test = [
'http://www.youtube.com/watch?v=5Y6HSHwhVlY',
'http://youtu.be/5Y6HSHwhVlY',
'http://www.youtube.com/embed/5Y6HSHwhVlY?rel=0" frameborder="0"',
'https://www.youtube-nocookie.com/v/5Y6HSHwhVlY?version=3&hl=en_US',
'http://www.youtube.com/',
'http://www.youtube.com/?feature=ytca']
for url in youtube_urls_test:
m = youtube_url_validation(url)
if m:
print 'OK {}'.format(url)
print m.groups()
print m.group(6)
else:
print 'FAIL {}'.format(url)
答案 1 :(得分:5)
您应该将正则表达式指定为原始字符串。
你不必逃避看起来特殊的每个角色,只有那些 的角色。
您可以使用(foo|)
,而不是指定空分支(?
)来制作可选内容。
如果要在字符集中包含-
,则必须将其转义或将其放在开始括号后面。
您可以使用\w
等特殊字符集(等于[a-zA-Z0-9_]
)来缩短正则表达式。
r'(https?://)?(www\.)?youtube\.(com|nl)/watch\?v=([-\w]+)'
现在,为了匹配整个网址,您必须考虑输入中可以或不可以遵循的内容。然后你把它放到一个前瞻组(你不想消耗它)。
在这个例子中,除了-
,=
,%
,&
和字母数字字符外,我还接受了所有内容来结束网址(懒得想更难)
.*?
非贪婪地使用了v-argument和URL末尾之间的所有内容。
r'(https?://)?(www\.)?youtube\.(com|nl)/watch\?v=([\w-]+)(&.*?)?(?=[^-\w&=%])'
但是,我不会过分相信这个一般的解决方案。众所周知,用户输入很难解析。
答案 2 :(得分:3)
如果您使用urlparse module选择找到的YouTube地址并将其恢复为您想要的格式,该怎么办?然后你可以简化你的正则表达式,这样它只能找到整个网址然后使用urlparse来为你挑选它。
from urlparse import urlparse,parse_qs,urlunparse
from urllib import urlencode
youtube_url = urlparse('http://www.youtube.com/watch?v=aFNzk7TVUeY&feature=grec_index')
params = parse_qs(youtube_url.query)
new_params = {'v': params['v'][0]}
cleaned_youtube_url = urlunparse((youtube_url.scheme, \
youtube_url.netloc, \
youtube_url.path,
None, \
urlencode(new_params), \
youtube_url.fragment))
这是一些代码,但它可以让你避免正则表达式的疯狂。
正如Hop所说,你应该使用原始字符串作为正则表达式。
答案 3 :(得分:0)
以下是我在脚本中实现的方法:
string = "Hey, check out this video: https://www.youtube.com/watch?v=bS5P_LAqiVg"
youtube = re.findall(r'(https?://)?(www\.)?((youtube\.(com))/watch\?v=([-\w]+)|youtu\.be/([-\w]+))', string)
if youtube:
print youtube
输出:
["", "youtube.com/watch?v=BS5P_LAqiVg", ".com", "watch", "com", "bS5P_LAqiVg", ""]
例如,如果您只想获取视频ID,则可以执行以下操作:
video_id = [c for c in youtube[0] if c] # Get rid of empty list objects
video_id = video_id[len(video_id)-1] # Return the last item in the list