代码之家  ›  专栏  ›  技术社区  ›  Jason Coon

如何在Python中将扩展ASCII转换为HTML实体名?

  •  3
  • Jason Coon  · 技术社区  · 14 年前

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

    我想做的是转换成HTML实体名等价物(即。 © 而不是 © ). 下面这个小程序显示了我正在尝试做的失败的事情。除了查找/替换之外,还有其他方法可以做到这一点吗?

    #coding=latin-1
    
    def convertEntities(s):
        return s.encode('ascii', 'xmlcharrefreplace')
    
    ok = 'ascii: !@#$%^&*()<>'
    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
    
    5 回复  |  直到 14 年前
        1
  •  2
  •   Wai Yip Tung    14 年前

    htmlentitydefs 你想要什么?

    import htmlentitydefs
    htmlentitydefs.codepoint2name.get(ord(c),c)
    
        2
  •  2
  •   Wayne Werner    14 年前

    编辑

    其他人提到了 htmlentitydefs

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

    这应该管用。

        3
  •  1
  •   SiggyF    14 年前

    我不知道有多直接,但我认为 htmlentitydefs here .

        4
  •  1
  •   Jason Coon    14 年前

    这就是我将要使用的解决方案,其中有一个小补丁,用于检查entitydefs是否包含我们所拥有的角色的映射。

    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
    
        5
  •  0
  •   Duncan    14 年前

    您确定不希望转换是可逆的吗?你的 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: !@#$%^&*()<>'
    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