【问题标题】:How to Convert Extended ASCII to HTML Entity Names in Python?如何在 Python 中将扩展的 ASCII 转换为 HTML 实体名称?
【发布时间】:2011-03-19 18:35:39
【问题描述】:

我目前正在这样做以将扩展 ascii 字符替换为它们的 HTML-entity-number 等效项:

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

【问题讨论】:

    标签: python html encoding ascii


    【解决方案1】:

    htmlentitydefs是你想要的吗?

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

    【讨论】:

    • 是的,这就是我要找的东西....虽然还没有。我想我有一个基于此的解决方案
    【解决方案2】:

    编辑

    其他人提到了我从不知道的htmlentitydefs。它将以这种方式与我的代码一起使用:

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

    这应该可行。

    【讨论】:

    • 这就是为什么我说“除了查找/替换”,换句话说,我不想建立一个 128 个字符的字典。这个解决方案适用于我发布的代码
    • 好吧,我刚刚调整了我的代码以使用其他人提到的htmlentitydefs。现在您不必构建它:)
    • 看起来更好...可能需要添加一些对 ASCII 码的检查,因为我不希望将“&lt;
    • entitydefs.get('&lt;', False) => False - 这只是一种替换方式:for e in entitydefs: print e 查看所有标签。
    【解决方案3】:

    我不确定如何直接使用,但我认为htmlentitydefs 模块会很有用。可以在here 找到一个示例。

    【讨论】:

      【解决方案4】:

      更新这是我要使用的解决方案,有一个小修复来检查 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】:

        您确定不希望转换是可逆的吗?您的 ok_expected 字符串表示您不希望现有的 &amp; 字符转义,因此转换将是一种方式。下面的代码假定 &amp; 应该被转义,但如果你真的不想这样,只需删除 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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-18
          • 1970-01-01
          相关资源
          最近更新 更多