处理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()

留下回复