Вопрос по python, html, regex – Обнаружение URL-адресов в строке и перенос с тегом «
7

Я пытаюсь написать что-то, что кажется достаточно простым, но по какой-то причине мне трудно обдумать это.

Я ищу написать функцию Python, которая при передаче строки передаст эту строку обратно с HTML-кодировкой вокруг URL-адресов.

unencoded_string = "This is a link - http://google.com"

def encode_string_with_links(unencoded_string):
    # some sort of regex magic occurs
    return encoded_string

print encoded_string

'This is a link - <a href="http://google.com">http://google.com</a>'

Спасибо!

Вы действительно можете рассчитывать на URL, чтобы начать с & quot; http & quot ;? Часто я вижу URL-адреса, записанные как & quot; example.com/foo" ;. Вы хотите / должны соответствовать этому также? Stan Graves
Это действительно хороший момент - я определенно хочу обнаружить google.com, а такжеgoogle.com - Я собираюсь еще раз взглянуть на гигантский ответ Google, который был представлен, так как это может быть лучше. Patrick Harrington

Ваш Ответ

2   ответа
8

"Волшебство регулярного выражения" тебе нужно простоsub (который делает замену):

def encode_string_with_links(unencoded_string):
  return URL_REGEX.<a href="\1">\1</a>', unencoded_string)

URL_REGEX может быть что-то вроде:

URL_REGEX = re.compile(r'''((?:mailto:|ftp://|http://)[^ <>'"{}|\\^`[\]]*)''')

Это довольно слабое регулярное выражение для URL-адресов: оно позволяет использовать схемы mailto, http и ftp, и после этого практически просто продолжает работать, пока не столкнется с «небезопасным». символ (кроме процентов, которые вы хотите разрешить для побегов). Вы можете сделать это более строгим, если вам нужно. Например, вы можете потребовать, чтобы за процентами следовал допустимый шестнадцатеричный escape, или разрешить только один знак фунта (для фрагмента) или установить порядок между параметрами запроса и фрагментами. Этого должно быть достаточно, чтобы вы начали.

7

#---------- find_urls.py----------#
# Functions to identify and extract URLs and email addresses

import re

def fix_urls(text):
    pat_url = re.compile(  r'''
                     (?x)( # verbose identify URLs within text
         (http|ftp|gopher) # make sure we find a resource type
                       :// # ...needs to be followed by colon-slash-slash
            (\w+[:.]?){2,} # at least two domain groups, e.g. (gnosis.)(cx)
                      (/?| # could be just the domain name (maybe w/ slash)
                [^ \n\r"]+ # or stuff then space, newline, tab, quote
                    [\w/]) # resource name ends in alphanumeric or slash
         (?=[\s\.,>)'"\]]) # assert: followed by white or clause ending
                         ) # end of match group
                           ''')
    pat_email = re.compile(r'''
                    (?xm)  # verbose identify URLs in text (and multiline)
                 (?=^.{11} # Mail header matcher
         (?<!Message-ID:|  # rule out Message-ID's as best possible
             In-Reply-To)) # ...and also In-Reply-To
                    (.*?)( # must grab to email to allow prior lookbehind
        ([A-Za-z0-9-]+\.)? # maybe an initial part: [email protected]
             [A-Za-z0-9-]+ # definitely some local user: [email protected]
                         @ # ...needs an at sign in the middle
              (\w+\.?){2,} # at least two domain groups, e.g. (gnosis.)(cx)
         (?=[\s\.,>)'"\]]) # assert: followed by white or clause ending
                         ) # end of match group
                           ''')

    for url in re.findall(pat_url, text):
       text = text.replace(url[0], '<a href="%(url)s">%(url)s</a>' % {"url" : url[0]})

    for email in re.findall(pat_email, text):
       text = text.replace(email[1], '<a href="mailto:%(email)s">%(email)s</a>' % {"email" : email[1]})

    return text

if __name__ == '__main__':
    print fix_urls("test http://google.com asdasdasd some more text")

EDIT: С учетом ваших потребностей

Похожие вопросы