【问题标题】:Detect URLs in a string and wrap with "<a href..." tag检测字符串中的 URL 并用“<a href...”标签包装
【发布时间】:2010-11-07 10:58:02
【问题描述】:

我想写一些看起来应该很容易的东西,但无论出于何种原因,我都很难理解它。

我正在寻找编写一个 python 函数,当传递一个字符串时,将通过 URL 周围的 HTML 编码将该字符串传回。

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>'

谢谢!

【问题讨论】:

  • 你真的可以依赖以“http”开头的 URL 吗?我经常看到 URLS 写成“example.com/foo”。你也想/需要匹配吗?
  • 这是一个非常好的观点 - 我当然想检测 google.com 以及 google.com - 我将再看一下提交的巨大谷歌答案,因为那可能是更合适。

标签: python html regex


【解决方案1】:

Google 解决方案:

#---------- 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: DAVID.mertz@gnosis.cx
             [A-Za-z0-9-]+ # definitely some local user: MERTZ@gnosis.cx
                         @ # ...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")

编辑:根据您的需要进行调整

【讨论】:

    【解决方案2】:

    您需要的“正则表达式魔法”只是 sub(它进行替换):

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

    URL_REGEX 可能类似于:

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

    这是一个非常松散的 URL 正则表达式:它允许 mailto、http 和 ftp 方案,然后几乎一直运行,直到遇到“不安全”字符(百分比除外,您希望允许转义) .如果需要,您可以使其更严格。例如,您可以要求百分比后跟有效的十六进制转义,或者只允许一个井号(对于片段)或强制查询参数和片段之间的顺序。不过,这应该足以让您入门。

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多