2011-07-31 6 views
3

파이썬에서 HTML 코드를 처리 할 때 특수 문자 때문에 다음 코드를 사용해야합니다.string.replace 문의 순서를 더 읽기 좋게 만들기

line = string.replace(line, """, "\"") 
line = string.replace(line, "'", "'") 
line = string.replace(line, "&", "&") 
line = string.replace(line, "&lt;", "<") 
line = string.replace(line, "&gt;", ">") 
line = string.replace(line, "&laquo;", "<<") 
line = string.replace(line, "&raquo;", ">>") 
line = string.replace(line, "&#039;", "'") 
line = string.replace(line, "&#8220;", "\"") 
line = string.replace(line, "&#8221;", "\"") 
line = string.replace(line, "&#8216;", "\'") 
line = string.replace(line, "&#8217;", "\'") 
line = string.replace(line, "&#9632;", "") 
line = string.replace(line, "&#8226;", "-") 

내가 대체해야 할 특수 문자가 훨씬 더 많아 보입니다. 이 코드를 더 우아하게 만드는 방법을 알고 있습니까?

string.replacestr/ unicode 객체의 방법으로 간단하게 사용할 수 있는지 당신이

+0

가능한 중복 [파이썬 문자열에서 HTML 엔티티 디코딩?] (http://stackoverflow.com/questions/2087370/decode-html-entities-in-python-string) –

+1

'string.replace'와'string'에서 가장 유사한 함수들 모듈 le는 더 이상 사용되지 않습니다. http://docs.python.org/library/string.html#deprecated-string-functions –

+0

@Ben James 감사합니다.이 솔루션은 나에게 적합하지만 중복성이 없습니다. 다른 교체 순서 (예. HTML 특수 문자 이외의 다른 것에 따라 1000 개가 넘는 대체물) – xralf

답변

4
REPLACEMENTS = [ 
    ("&quot;", "\""), 
    ("&apos;", "'"), 
    ... 
    ] 
for entity, replacement in REPLACEMENTS: 
    line = line.replace(entity, replacement) 

참고 감사합니다.

더 나은 것은 아직 this question입니다.

질문의 제목은 최적화, 즉 더 빠르게 실행됩니다. 이것은 완전히 다른 문제이며 더 많은 작업이 필요합니다.

+0

맞습니다. "optimization"이라는 단어를 "가독성"으로 바꿀 것입니다. – xralf

+2

대체 순서는 항상 중요합니다. "&"을''& "로 바꾸면"& lt; "잘못된 순서로 수행하면'<'로 표시됩니다. 일반적인 대체 패턴이있는 경우에는 're.sub'를 사용하여 해당 패턴을 찾고 대체 기능을 사용하는 함수를 사용하여 HTML 엔티티와 같은 기능을 수행 할 수 있습니다. –

2

HTML 엔티티를 디코딩하기 위해 내가 작성한 코드는 다음과 같습니다. Python 2.x의 경우, str에서 unicode까지 디코딩 할 수 있습니다. 현대 Python을 사용하고 있다면이 비트를 삭제할 수 있습니다. 나는 그것이 명명 된 엔티티, 십진수 및 16 진수 엔터티를 처리한다고 생각합니다. 몇 가지 이유 'APOS'내가 먼저 복사하고 추가 할 수 있도록라는 단체의 파이썬의 사전에없는 위해 하나 누락 :

from htmlentitydefs import name2codepoint 
name2codepoint = name2codepoint.copy() 
name2codepoint['apos']=ord("'") 

EntityPattern = re.compile('&(?:#(\d+)|(?:#x([\da-fA-F]+))|([a-zA-Z]+));') 
def decodeEntities(s, encoding='utf-8'): 
    def unescape(match): 
     code = match.group(1) 
     if code: 
      return unichr(int(code, 10)) 
     else: 
      code = match.group(2) 
      if code: 
       return unichr(int(code, 16)) 
      else: 
       code = match.group(3) 
       if code in name2codepoint: 
        return unichr(name2codepoint[code]) 
     return match.group(0) 

    if isinstance(s, str): 
     s = s.decode(encoding) 
    return EntityPattern.sub(unescape, s) 
2

최적화

REPL_tu = (("&quot;", "\"") , ("&apos;", "'") , ("&amp;", "&") , 
      ("&lt;", "<") , ("&gt;", ">") , 
      ("&laquo;", "<<") , ("&raquo;", ">>") , 
      ("&#039;", "'") , 
      ("&#8220;", "\"") , ("&#8221;", "\"") , 
      ("&#8216;", "\'") , ("&#8217;", "\'") , 
      ("&#9632;", "") , ("&#8226;", "-") ) 

def repl(mat, d = dict(REPL_tu)): 
    return d[mat.group()] 

import re 
regx = re.compile('|'.join(a for a,b in REPL_tu)) 

line = 'A tag &lt;bidi&gt; has a &quot;weird&#8220;&#8226;&apos;content&apos;' 
modline = regx.sub(repl,line) 
print 'Exemple:\n\n'+line+'\n'+modline 








from urllib import urlopen 

print '\n-----------------------------------------\nDownloading a web source:\n' 
sock = urlopen('http://www.mythicalcreaturesworld.com/greek-mythology/monsters/python-the-serpent-of-delphi-%E2%80%93-python-the-guardian-dragon-and-apollo/') 
html_source = sock.read() 
sock.close() 

from time import clock 

n = 100 

te = clock() 
for i in xrange(n): 
    res1 = html_source 
    res1 = regx.sub(repl,res1) 
print 'with regex ',clock()-te,'seconds' 


te = clock() 
for i in xrange(n): 
    res2 = html_source 
    for entity, replacement in REPL_tu: 
     res2 = res2.replace(entity, replacement) 
print 'with replace',clock()-te,'seconds' 

print res1==res2 

결과

Exemple: 

A tag &lt;bidi&gt; has a &quot;weird&#8220;&#8226;&apos;content&apos; 
A tag <bidi> has a "weird"-'content' 

----------------------------------------- 
Downloading a web source: 

with regex 0.097578323502 seconds 
with replace 0.213866846205 seconds 
True 
관련 문제