2009-07-01 23 views
6

私はそれが簡単なように思える何かを書こうとしていますが、何らかの理由で私は周りを頭に抱いていますそれ。文字列のURLを検出し、 "<a href ..."タグで囲みます

私は、文字列を渡すと、その文字列をURLの回りにHTMLエンコーディングで戻すようなPython関数を記述しようとしています。

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

ありがとうございます!

+1

本当に "http"で始まるURLに頼ることはできますか?しばしば、私は "example.com/foo"と書かれたURLを参照しています。あなたもそれにマッチする必要がありますか? –

+0

これは本当に良い点です。私は確かにgoogle.comとhttp://google.comを検出したいと思っています。私は提出された巨大なgoogleの回答をもう一度見ていきます。 。 –

答えて

8

"正規表現の魔法" あなたが必要とする調整はちょうど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のスキームを許可し、その後は「安全でない」文字になるまで続けます。エスケープ)。あなたが必要ならばもっと厳しくすることができます。たとえば、パーセントに有効な16進エスケープが続くか、または1つのシャープ記号(フラグメントの場合)のみを許可するか、クエリパラメータとフラグメントの間の順序を強制するように指定できます。しかし、これはあなたを始めるのに十分なはずです。

6

ググソリューション:

#---------- 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:ニーズ

関連する問題