处理Windos中文文本的python脚本:定长换行
作者:半瓶墨水 链接:http://www.2maomao.com/blog/python-trimit/
写这个的原因,说起来,唉,恼火啊。
昨天晚上下载了一部小说,纯文本的,没有阅读器,拿浏览器直接打开,发现浏览器太宽,读起来不爽,又不想因为这个单独开个小浏览器窗口。
不知道怎么着,想搞个工具来个定长换行,把文本行长度大于40个汉字的强制换行,再用浏览器看。
我对于Ruby比较熟悉,前面写过一些Ruby的文章。
搞了一个半小时,处理GBK和UTF8的搞定了,Unicode的还是搞不定,这个和Windows文本的文件头有关系,但是更关键的是,Ruby处理中文上的缺陷。
C++处理中文,就只有一种方法:字节码,自己调用API转吧。就两个API,累了点儿,好歹知道怎么做,不行就二进制自己编码解码好了。
Ruby呢?
据我所知Ruby有不下5种解决方案,可是当我想找一种来解决我遇到的这个问题,好像哪种都不靠谱。
又搞了一会儿,这时候我完全没有心情去看小说了。
我放弃了Ruby,转入C++,半小时搞定,用浏览器打开看了一眼结果。
嗯,不错。
然后就去睡觉了。
早晨起来,依旧恼火,据说Python处理中文有一套,上网抓了本Python的书下来,搞了一个小时。
现在可以读取windows文本文件,包括Unicode(Big-Endien/Little-Endien)、UTF8,以及GBK编码的文件。
效果还不错。不过这个方法似乎有些笨,感觉像是拿斧头劈开了孔明锁。
下载: trimit.py
import sys
#-----------------------------------------------
def show_help():
print
print " Usage:"
print " pp file_name output_file [width]"
print
#-----------------------------------------------
def uni_read(fin, unicode):
if not unicode:
return fin.readline()
str = ""
temp = fin.read(2)
line_end = '\n\x00'
if unicode == 2:
line_end = '\x00\n'
while (temp):
if temp == line_end:
break
str += temp
temp = fin.read(2)
return str
#-----------------------------------------------
if len(sys.argv) != 3 and len(sys.argv) != 4:
show_help()
exit()
limit = 40
if len(sys.argv) == 4:
limit = sys.argv[3]
fin = open(sys.argv[1], 'rb')
fout = open(sys.argv[2], 'wb')
head = fin.read(3)
codec = "mbcs"
unicode = 0
if head[0:2] == '\xff\xfe' :
codec = "utf-16-le"
unicode = 1
fin.seek(2)
elif head[0:2] == '\xfe\xff' :
codec = "utf-16-be"
unicode = 2
fin.seek(2)
elif head == '\xef\xbb\xbf':
codec = "utf-8"
fin.seek(3)
else:
fin.seek(0)
print "codec = " + codec
line = uni_read(fin, unicode)
print line.decode(codec)
while line:
pos = 0
line = line.decode(codec)
if line[-2:] == '\r\n':
line = line[0:-2]
while len(line) - pos > 0:
part = line[pos:pos+limit]
part = part.encode("utf-8")
print >> fout, part
pos += limit
line = uni_read(fin, unicode)
fin.close()
fout.close()
#-----------------------------------------------
def show_help():
print " Usage:"
print " pp file_name output_file [width]"
#-----------------------------------------------
def uni_read(fin, unicode):
if not unicode:
return fin.readline()
str = ""
temp = fin.read(2)
line_end = '\n\x00'
if unicode == 2:
line_end = '\x00\n'
while (temp):
if temp == line_end:
break
str += temp
temp = fin.read(2)
return str
#-----------------------------------------------
if len(sys.argv) != 3 and len(sys.argv) != 4:
show_help()
exit()
limit = 40
if len(sys.argv) == 4:
limit = sys.argv[3]
fin = open(sys.argv[1], 'rb')
fout = open(sys.argv[2], 'wb')
head = fin.read(3)
codec = "mbcs"
unicode = 0
if head[0:2] == '\xff\xfe' :
codec = "utf-16-le"
unicode = 1
fin.seek(2)
elif head[0:2] == '\xfe\xff' :
codec = "utf-16-be"
unicode = 2
fin.seek(2)
elif head == '\xef\xbb\xbf':
codec = "utf-8"
fin.seek(3)
else:
fin.seek(0)
print "codec = " + codec
line = uni_read(fin, unicode)
print line.decode(codec)
while line:
pos = 0
line = line.decode(codec)
if line[-2:] == '\r\n':
line = line[0:-2]
while len(line) - pos > 0:
part = line[pos:pos+limit]
part = part.encode("utf-8")
print >> fout, part
pos += limit
line = uni_read(fin, unicode)
fin.close()
fout.close()


