alv*_*vas 13 python regex unicode io control-characters
import unicodedata, re, io
all_chars = (unichr(i) for i in xrange(0x110000))
control_chars = ''.join(c for c in all_chars if unicodedata.category(c)[0] == 'C')
cc_re = re.compile('[%s]' % re.escape(control_chars))
def rm_control_chars(s): # see http://www.unicode.org/reports/tr44/#General_Category_Values
return cc_re.sub('', s)
cleanfile = []
with io.open('filename.txt', 'r', encoding='utf8') as fin:
for line in fin:
line =rm_control_chars(line)
cleanfile.append(line)
Run Code Online (Sandbox Code Playgroud)
我想保留文件中的换行符.
以下记录cc_re.sub('', s)替换前几行所用的时间(第一列是所用时间,第二列是len(s)):
0.275146961212 251
0.672796010971 614
0.178567171097 163
0.200030088425 180
0.236430883408 215
0.343492984772 313
0.317672967911 290
0.160616159439 142
0.0732028484344 65
0.533437013626 468
0.260229110718 236
0.231380939484 204
0.197766065598 181
0.283867120743 258
0.229172945023 208
Run Code Online (Sandbox Code Playgroud)
正如@ashwinichaudhary建议的那样,使用s.translate(dict.fromkeys(control_chars))和记录输出的时间相同:
0.464188098907 252
0.366552114487 615
0.407374858856 164
0.322507858276 181
0.35142993927 216
0.319973945618 314
0.324357032776 291
0.371646165848 143
0.354818105698 66
0.351796150208 469
0.388131856918 237
0.374715805054 205
0.363368988037 182
0.425950050354 259
0.382766962051 209
Run Code Online (Sandbox Code Playgroud)
但是我的1GB文本代码真的很慢.有没有其他方法来清理受控角色?
通过charater找到了一个解决方案工作角色,我用100K文件标记它:
import unicodedata, re, io
from time import time
# This is to generate randomly a file to test the script
from string import lowercase
from random import random
all_chars = (unichr(i) for i in xrange(0x110000))
control_chars = [c for c in all_chars if unicodedata.category(c)[0] == 'C']
chars = (list(u'%s' % lowercase) * 115117) + control_chars
fnam = 'filename.txt'
out=io.open(fnam, 'w')
for line in range(1000000):
out.write(u''.join(chars[int(random()*len(chars))] for _ in range(600)) + u'\n')
out.close()
# version proposed by alvas
all_chars = (unichr(i) for i in xrange(0x110000))
control_chars = ''.join(c for c in all_chars if unicodedata.category(c)[0] == 'C')
cc_re = re.compile('[%s]' % re.escape(control_chars))
def rm_control_chars(s):
return cc_re.sub('', s)
t0 = time()
cleanfile = []
with io.open(fnam, 'r', encoding='utf8') as fin:
for line in fin:
line =rm_control_chars(line)
cleanfile.append(line)
out=io.open(fnam + '_out1.txt', 'w')
out.write(''.join(cleanfile))
out.close()
print time() - t0
# using a set and checking character by character
all_chars = (unichr(i) for i in xrange(0x110000))
control_chars = set(c for c in all_chars if unicodedata.category(c)[0] == 'C')
def rm_control_chars_1(s):
return ''.join(c for c in s if not c in control_chars)
t0 = time()
cleanfile = []
with io.open(fnam, 'r', encoding='utf8') as fin:
for line in fin:
line = rm_control_chars_1(line)
cleanfile.append(line)
out=io.open(fnam + '_out2.txt', 'w')
out.write(''.join(cleanfile))
out.close()
print time() - t0
Run Code Online (Sandbox Code Playgroud)
输出是:
114.625444174
0.0149750709534
Run Code Online (Sandbox Code Playgroud)
我尝试了一个1Gb的文件(仅用于第二个),它持续了186s.
我还写了相同脚本的其他版本,稍快(176s),内存效率更高(对于不适合RAM的非常大的文件):
t0 = time()
out=io.open(fnam + '_out5.txt', 'w')
with io.open(fnam, 'r', encoding='utf8') as fin:
for line in fin:
out.write(rm_control_chars_1(line))
out.close()
print time() - t0
Run Code Online (Sandbox Code Playgroud)
与在UTF-8中一样,所有控制字符都以1字节(与ASCII兼容)编码,而在32以下,我建议使用这段快速的代码:
#!/usr/bin/python
import sys
ctrl_chars = [x for x in range(0, 32) if x not in (ord("\r"), ord("\n"), ord("\t"))]
filename = sys.argv[1]
with open(filename, 'rb') as f1:
with open(filename + '.txt', 'wb') as f2:
b = f1.read(1)
while b != '':
if ord(b) not in ctrl_chars:
f2.write(b)
b = f1.read(1)
Run Code Online (Sandbox Code Playgroud)
可以吗?
| 归档时间: |
|
| 查看次数: |
570 次 |
| 最近记录: |