2009-07-01 4 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://)[^ <>'"{}|\\^`[\]]*)''') 

이것은 mailto, http 및 ftp 체계를 허용하며, "안전하지 않은"문자가 나오기 전까지 계속 유지됩니다 (퍼센트를 제외하고는 허용하고 싶은). 탈출구). 필요한 경우 더 엄격하게 만들 수 있습니다. 예를 들어, 퍼센트에 유효한 16 진수 이스케이프가 오도록하거나, 단편에 대해 파운드 기호 하나만 허용하거나 쿼리 매개 변수와 단편간에 순서를 적용하도록 요구할 수 있습니다. 그래도 시작하기에 충분할 것입니다.

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") 

편집 :의 요구

관련 문제