2011-01-16 2 views
5

Я создаю регулярное выражение, чтобы я мог найти ссылки youtube (может быть несколько) в куске текста HTML, размещенного пользователем.Python regex convert youtube url to youtube video

В настоящее время я использую следующее регулярное выражение для изменения «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) 

(где переменного «тег» является немного HTML, так что видеоработы и «значение» пост пользователя)

Теперь это работает .. до тех пор, пока URL выглядит так:

«http://www.youtube.com/watch? v = -JyZLS2IhkQ & особенность ... '

Теперь я надеюсь, что вы, ребята, могли бы помочь мне понять, как также совместить функцию «& ...», чтобы она исчезла.

Пример HTML:

No replies to this post.. 

Youtube vid: 

http://www.youtube.com/watch?v=-JyZLS2IhkQ 

More blabla 

Спасибо за ваши мысли, высоко ценится

Стефан

+3

ваше регулярное выражение довольно зверским :) – hop

+0

ждать чего? вы пытаетесь _find_ a youtube ссылку похоронили в каком-то html-коде? Мне было трудно разобрать это из вашего вопроса! – hop

+0

Прошу прощения за плохой вопрос, я изменил пост, надеюсь, теперь это станет более ясным. – Frits

ответ

4

Вы должны указать свои регулярные выражения в качестве исходных строк.

Вы не должны бежать каждый персонаж, который выглядит специальные, только те, которые являются .

Вместо указания пустой ветви ((foo|)), чтобы сделать что-то дополнительно, вы можете использовать ?.

Если вы хотите включить - в набор символов, вам нужно сбежать от него или поместить его сразу после открывающей скобки.

Вы можете использовать специальные наборы символов, такие как \w (equals [a-zA-Z0-9_]), чтобы сократить ваше регулярное выражение.

r'(https?://)?(www\.)?youtube\.(com|nl)/watch\?v=([-\w]+)' 

Теперь, чтобы соответствовать всему URL-адресу, вы должны думать о том, что может или не может следовать ему во входном файле. Затем вы помещаете это в группу взглядов (вы не хотите ее потреблять).

В этом примере я взял все, кроме -, =, %, & и алфавитно-цифровых символов, чтобы положить конец URL (слишком ленив, чтобы думать об этом тяжелее).

Все, что связано с v-аргументом и концом URL-адреса, не является жадным потреблением .*?.

r'(https?://)?(www\.)?youtube\.(com|nl)/watch\?v=([\w-]+)(&.*?)?(?=[^-\w&=%])' 

Тем не менее, я бы не стал слишком верить в это общее решение. Вклад пользователя, как известно, трудно проработать.

3

Что делать, если вы использовали urlparse module, чтобы разобрать адрес youtube, который вы нашли, и вернуть его в желаемый формат? Затем вы можете упростить свое регулярное выражение так, чтобы оно находило только весь URL-адрес, а затем использовало 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)) 

Это немного больше кода, но это позволяет избежать безумия регулярных выражений.

И, как сказал хоп, вы должны использовать необработанные строки для регулярного выражения.

+0

Я дал (и удалил) тот же ответ, но проблема, как и было задано, - это на самом деле _find_ url, а не разобрать его. – hop

+0

Ну, он хочет сделать то и другое. Он хочет найти URL и разобрать его (потому что ему нужно избавиться от части строки запроса). Мое предложение состояло в том, чтобы сначала найти URL-адрес, который его регулярное выражение уже делает в соответствии с вопросом. И затем используйте какой-то уже существующий код, чтобы разделить его и разделить то, что он не хочет или не нуждается. – seggy

5

Вот как я ее решения:

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) 
+2

Чтобы сопоставить URL-адреса, например 'http://www.youtube.com/watch?feature=player_detailpage & v = QemTZn8YfJ0 # t = 46s' Я отредактировал ваше регулярное выражение на' youtube_regex = ( r '(https?: //)? (www \.)? ' ' (youtube | youtu | youtube-nocookie) \. (com | be)/' ' (смотреть \?. *? (? = v =) v = | embed/| v/|.? + \ v =) ([?^& =% \] {11}) ') ' –

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", ""] 

Если вы просто хотели, чтобы захватить идентификатор видео, например, вы могли бы сделать:

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