2010-07-22 3 views
3

나는 현재이 자신의 HTML 엔터티 번호 등가물로 확장 된 ASCII 문자를 교체하고 있어요 : 내가하고 싶은 무엇파이썬에서 확장 ASCII를 HTML 엔티티 이름으로 변환하는 방법은 무엇입니까?

s.encode('ascii', 'xmlcharrefreplace') 

대신합니다 (HTML 엔티티 이름의 동등한 즉 © 변환입니다 ©). 아래의이 작은 프로그램은 내가 실패하려고하는 것을 보여줍니다. 찾기/바꾸기를 제외하고는이 작업을 수행 할 수있는 방법이 있습니까?

#coding=latin-1 

def convertEntities(s): 
    return s.encode('ascii', 'xmlcharrefreplace') 

ok = 'ascii: [email protected]#$%^&*()<>' 
not_ok = u'extended-ascii: ©®°±¼' 

ok_expected = ok 
not_ok_expected = u'extended-ascii: &copy;&reg;&deg;&plusmn;&frac14;' 

ok_2 = convertEntities(ok) 
not_ok_2 = convertEntities(not_ok) 

if ok_2 == ok_expected: 
    print 'ascii worked' 
else: 
    print 'ascii failed: "%s"' % ok_2 

if not_ok_2 == not_ok_expected: 
    print 'extended-ascii worked' 
else: 
    print 'extended-ascii failed: "%s"' % not_ok_2 

답변

1

업데이트 이것은 우리가 가지고있는 캐릭터에 대한 매핑이 엔티티 정의에 들어 있는지 확인하기위한 작은 수정으로 해결할 해결책입니다.

def convertEntities(s): 
    return ''.join([getEntity(c) for c in s]) 

def getEntity(c): 
    ord_c = ord(c) 
    if ord_c > 127 and ord_c in htmlentitydefs.codepoint2name: 
     return "&%s;" % htmlentitydefs.codepoint2name[ord_c] 
    return c 
2

편집

다른 사람들은 내가 대해 알고 결코 htmlentitydefs을 언급했다. 그것은 내 코드와 같은 방식으로 작동합니다 :

from htmlentitydefs import entitydefs as symbols 

for tag, val in symbols.iteritems(): 
    mystr = mystr.replace("&{0};".format(tag), val) 

그리고 그게 작동합니다.

+0

그래서 "찾기/바꾸기"를 제외하고 말했습니다. 즉, 128 문자의 사전을 작성하고 싶지 않습니다. 이 솔루션은 내가 게시 한 코드에서 작동 할 것이다. –

+0

글쎄, 나는 다른 사람들이 언급 한'htmlentitydefs'를 사용하기 위해 코드를 수정했다. 이제는 빌드 할 필요가 없습니다 :) –

+0

더 좋게 보입니다 ... "<"가 '<' –

2

htmlentitydefs 무엇을 원하십니까?

import htmlentitydefs 
htmlentitydefs.codepoint2name.get(ord(c),c) 
+0

네, 그게 내가 찾고있는 .... 꽤 아직 거기. 나는 이것에 기초한 해결책을 가지고 있다고 생각한다. –

1

내가 어떻게 직접 모르겠지만 나는 htmlentitydefs 모듈이 유용 할 것이라 생각합니다. 예는 here입니다.

0

변환을 되돌릴 수 없습니까? ok_expected 문자열은 기존 & 문자를 이스케이프하지 않으려는 것을 의미하므로 변환은 한 가지 방법입니다. 아래 코드는 &을 이스케이프해야한다고 가정하지만 실제로 원하지 않는 경우 cgi.escape을 제거하면됩니다.

어쨌든 원래 접근 방식을 정규식 대체와 결합하면 이전과 같이 인코딩을 수행 한 다음 숫자 엔티티를 수정하면됩니다. 그렇게하면 getEntity 함수를 통해 모든 단일 문자를 매핑하지 않게됩니다.

#coding=latin-1 
import cgi 
import re 
import htmlentitydefs 

def replace_entity(match): 
    c = int(match.group(1)) 
    name = htmlentitydefs.codepoint2name.get(c, None) 
    if name: 
     return "&%s;" % name 
    return match.group(0) 

def convertEntities(s): 
    s = cgi.escape(s) # Remove if you want ok_expected to pass! 
    s = s.encode('ascii', 'xmlcharrefreplace') 
    s = re.sub("&#([0-9]+);", replace_entity, s) 
    return s 

ok = 'ascii: [email protected]#$%^&*()<>' 
not_ok = u'extended-ascii: ©®°±¼' 

ok_expected = ok 
not_ok_expected = u'extended-ascii: &copy;&reg;&deg;&plusmn;&frac14;' 

ok_2 = convertEntities(ok) 
not_ok_2 = convertEntities(not_ok) 

if ok_2 == ok_expected: 
    print 'ascii worked' 
else: 
    print 'ascii failed: "%s"' % ok_2 

if not_ok_2 == not_ok_expected: 
    print 'extended-ascii worked' 
else: 
    print 'extended-ascii failed: "%s"' % not_ok_2 
관련 문제