免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5473 | 回复: 7

求教一个字符编码转换的问题 [复制链接]

论坛徽章:
0
发表于 2012-01-08 12:15 |显示全部楼层
5可用积分
本帖最后由 legone2008 于 2012-01-08 12:16 编辑

需求背景:
   在一个日志文件中的数据既然有GBK格式数据,又有UTF-8格式的数据, 想用python做这样一个工作, 从文件中读取日志,

   如果我想看GBK数据日志,那么打印GBK格式日志, UTF-8日志可能就是乱码了;
   如果我想看UTF-8数据日志,那么打印UTF-8格式日志, GBK日志为乱码。

   不知道能不能做到自动识别编码格式,全部按自己格式正常输出,也就是没有乱码,全都是可识别字符,这样更好。
  1. #!/usr/bin/env python
  2. # -*- coding=gbk -*-

  3. a=u"中国人\n"

  4. outUTF = a.encode('utf-8')
  5. outGBK = a.encode('gbk')

  6. file="unicode.txt"
  7. f = open(file,"w")

  8. f.write("UTF-8:")
  9. f.write(outUTF)

  10. f.write("\n")

  11. f.write("GBK:")
  12. f.write(outGBK)
  13. f.close()


  14. f = open(file,"r")
  15. rline = f.read()
  16. print rline
复制代码

  1. UTF-8:涓?浗浜?

  2. GBK:中国人
复制代码
默认是输出GBK的好像,但不 知道怎么互相切换, 初学python,请教各位大侠了。 谢谢!

最佳答案

查看完整内容

python对多国语言的处理是支持的很好的,它可以处理现在任意编码的字符,这里深入的研究一下python对多种不同语言的处理。 有一点需要清楚的是,当python要做编码转换的时候,会借助于内部的编码,转换过程是这样的: 原有编码 -> 内部编码 -> 目的编码 python的内部是使用unicode来处理的,但是unicode的使用需要考虑的是它的编码格式有两种,一是UCS-2,它一共有65536个码位,另一种是UCS-4,它有2147483648g个码 ...

论坛徽章:
0
发表于 2012-01-08 12:15 |显示全部楼层

python对多国语言的处理是支持的很好的,它可以处理现在任意编码的字符,这里深入的研究一下python对多种不同语言的处理。
    有一点需要清楚的是,当python要做编码转换的时候,会借助于内部的编码,转换过程是这样的:
        原有编码 -> 内部编码 -> 目的编码
    python的内部是使用unicode来处理的,但是unicode的使用需要考虑的是它的编码格式有两种,一是UCS-2,它一共有65536个码位,另一种是UCS-4,它有2147483648g个码位。对于这两种格式,python都是支持的,这个是在编译时通过--enable- unicode=ucs2或--enable-unicode=ucs4来指定的。那么我们自己默认安装的python有的什么编码怎么来确定呢?有一个办法,就是通过sys.maxunicode的值来判断:

import  sys
print  sys.maxunicode


    如果输出的值为65535,那么就是UCS-2,如果输出是1114111就是UCS-4编码。
我们要认识到一点:当一个字符串转换为内部编码后,它就不是str类型了!它是unicode类型:

a  =   " 风卷残云 "
print  type(a)
b  =  a.unicode(a,  " gb2312 " )
print  type(b)


输出:
<type 'str'>
<type 'unicode'>

这个时候b可以方便的任意转换为其他编码,比如转换为utf-8:

c  =  b.encode( " utf-8 " )
print  c


c输出的东西看起来是乱码,那就对了,因为是utf-8的字符串。
    好了,该说说codecs模块了,它和我上面说的概念是密切相关的。codecs专门用作编码转换,当然,其实通过它的接口是可以扩展到其他关于代码方面的转换的,这个东西这里不涉及。

# -*- encoding: gb2312 -*-
import  codecs, sys

print   ' - ' * 60
# 创建gb2312编码器
look   =  codecs.lookup( " gb2312 " )
# 创建utf-8编码器
look2  =  codecs.lookup( " utf-8 " )

a  =   " 我爱北京 "

print  len(a), a
# 把a编码为内部的unicode, 但为什么方法名为decode呢,我的理解是把gb2312的字符串解码为unicode
b  =  look.decode(a)
# 返回的b[0]是数据,b[1]是长度,这个时候的类型是unicode了
print  b[ 1 ], b[0], type(b[0])
# 把内部编码的unicode转换为gb2312编码的字符串,encode方法会返回一个字符串类型
b2  =  look.encode(b[0])
# 发现不一样的地方了吧?转换回来之后,字符串长度由14变为了7! 现在的返回的长度才是真正的字数,原来的是字节数
print  b2[ 1 ], b2[0], type(b2[0])
# 虽然上面返回了字数,但并不意味着用len求b2[0]的长度就是7了,仍然还是14,仅仅是codecs.encode会统计字数
print  len(b2[0])


    上面的代码就是codecs的使用,是最常见的用法。另外还有一个问题就是,如果我们处理的文件里的字符编码是其他类型的呢?这个读取进行做处理也需要特殊的处理的。codecs也提供了方法.

# -*- encoding: gb2312 -*-
import  codecs, sys

# 用codecs提供的open方法来指定打开的文件的语言编码,它会在读取的时候自动转换为内部unicode
bfile  =  codecs.open( " dddd.txt " ,  ' r ' ,  " big5 " )
# bfile = open("dddd.txt", 'r')

ss  =  bfile.read()
bfile.close()
# 输出,这个时候看到的就是转换后的结果。如果使用语言内建的open函数来打开文件,这里看到的必定是乱码
print  ss, type(ss)


上面这个处理big5的,可以去找段big5编码的文件试试。


论坛徽章:
0
发表于 2012-01-08 12:44 |显示全部楼层
  1. f = codecs.open(file,"r",'utf-8','ignore')
  2. rline = f.read()
  3. print rline.encode('gbk','ignore')
复制代码
自己解决了,如果想看gbk的,就
  1. f = codecs.open(file,"r",'gbk','ignore')
复制代码

论坛徽章:
13
双鱼座
日期:2013-10-23 09:30:05数据库技术版块每日发帖之星
日期:2016-04-20 06:20:00程序设计版块每日发帖之星
日期:2016-03-09 06:20:002015亚冠之塔什干火车头
日期:2015-11-02 10:07:452015亚冠之德黑兰石油
日期:2015-08-30 10:07:07数据库技术版块每日发帖之星
日期:2015-08-28 06:20:00数据库技术版块每日发帖之星
日期:2015-08-05 06:20:002015年迎新春徽章
日期:2015-03-04 09:57:09辰龙
日期:2014-12-03 14:45:52酉鸡
日期:2014-07-23 09:46:23亥猪
日期:2014-03-13 08:46:22金牛座
日期:2014-02-11 09:36:21
发表于 2012-01-09 08:47 |显示全部楼层
其实楼主直接转成相同的编码不是更好

论坛徽章:
0
发表于 2012-01-09 08:55 |显示全部楼层
不错,不过我既想看UTF8的,也想看GBK的,是UTF8编码的就用UTF8显示,是GBK编码的就GBK显示。那又怎么实现呢?

论坛徽章:
0
发表于 2012-01-09 10:54 |显示全部楼层
咦 用不同的编码 也能区分~~果然牛逼~~~

论坛徽章:
0
发表于 2012-01-12 11:29 |显示全部楼层
回复 4# aixcradent
  1. f = open(file,'r')
  2. line = f.readline()
  3. while line:
  4.     try:
  5.         print unicode(line,'utf-8')#如果是utf-8编码的,就能正常打印,否则就会抛异常
  6.     except:
  7.         print unicode(line,'gbk')#本例中只有两种编码方式区别,utf-8抛异常,那肯定就是gbk了,所以在这里捕获异常,进行打印
  8.     line = f.readline()
  9. f.close()
复制代码

论坛徽章:
0
发表于 2012-08-27 16:10 |显示全部楼层
没有乱码,全都是可识别字符,这样更好。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP