Python 从大型unicode文本文件中删除符号

Python 从大型unicode文本文件中删除符号,python,regex,python-3.x,unicode,Python,Regex,Python 3.x,Unicode,我有一个文本文件,其中包含大约2GB的Unicode文本。我尝试使用以下代码删除所有符号 import re symbols = re.compile(r'[{} &+( )" =!.?.:.. / | » © : >< # « ,] 1 2 3 4 5 6 7 8 9 _ - + ; [ ] %',flags=re.UNICODE) with open('/home/corpus/All12.txt','a') as t: with open('/home

我有一个文本文件,其中包含大约2GB的Unicode文本。我尝试使用以下代码删除所有符号

import re
symbols = re.compile(r'[{} &+( )" =!.?.:.. / |  » © : >< #  «  ,] 1 2 3 4 5 6 7 8 9 _ - + ; [ ]  %',flags=re.UNICODE)

with open('/home/corpus/All12.txt','a') as t:
    with open('/home/corpus/All11.txt', 'r') as n:
        data = n.readline()          
        data = symbols.sub(" ", data)          
        t.write(data)
期望输出为
ന്യൂഡല്‍ഹി സര്‍ക്കാര്‍ജീവനക്കാരായ ഭര്‍ത്താക്കന്മാരുടെ ശമ്പളം。
代码不起作用。它停止了我的电脑


我能用out正则表达式解决这个问题吗?

第一个[和]之间的符号列表后面的re对我来说毫无意义。它不会删除符号粗体,但只会删除后跟“1 2 3 4 5 6 7 8 9”的符号;[ ] %'. 在其他工作中,re.sub不会执行任何操作。但不管怎样,您的代码运行在3.4.2,Win7上

import re
symbols = re.compile(r'[{} &+( )" =!.?.:.. / |  » © : >< #  «  ,]'
                     '1 2 3 4 5 6 7 8 9 _ - + ; [ ]  %',flags=re.UNICODE)
text = ('''" :621 " :621 :1 ;" _ " :594 :25 4 8 0 :23'''
        '''"സര്‍ക്കാര്‍ജീവനക്കാരുടെ ശമ്പളം അറിയാന്‍'''
        '''ഭാര്യമാര്‍ക്ക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍\n'''
        ''':621 :4 0 3 0 ;" _ " :551 :16 :3 " ''')
data = symbols.sub(" ", text)          
print(data == text)  # True

您需要在方括号中插入要替换的每个符号,转义一些特殊符号,如
[]
本身、单引号
'
\
。正则表达式是
r'[-0-9{}&+()“=!.?:/|»>>st='1234567890-=[]\,./\'!@$%^&*(+{}}):?/,`~ajshgasd'
>>>打印re.sub(r'[-0-9{}&+()“=!.?:/|»>>>fp=open('file.txt','r'))
>>>对于fp中的行:
…如果line.strip()='':continue#strip()删除前导空格和尾随空格

…打印re.sub(r'[-0-9{}&+()“=!.?:/|»>不带正则表达式的解决方案:

可以将“映射”功能与一组要删除的符号一起使用,以完成此操作

def removeSymbols(text,symbols):
    return "".join(map(lambda x: "" if x in symbols else x,text))

>>> string = '''" :621 \" :621 :1 ;\" _ \" :594 :25 4 8 0 :23 \"സര്‍ക്കാര്‍ജീവനക്കാരുടെ ശമ്പളം അറിയാന്‍ ഭാര്യമാരക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍\n:621 :4 0 3 0 ;\" _ \" :551 :16 :3"'''    

>>> symbols = set('[{} &+( )" =!.?.:.. / |  » © : >< #  «  ,] 1 2 3 4 5 6 7 8 9 _ - + ; [ ]  %')

>>> cleanString = removeSymbols(string,symbols)

>>> print(cleanString)

'" :621 " :621 :1 ;" _ " :594 :25 4 8 0 :23 "സര്\u200dക്കാര്\u200dജീവനക്കാരുടെ ശമ്പളം അറിയാന്\u200d ഭാര്യമാര്\u200dക്ക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്\u200d\n:621 :4 0 3 0 ;" _ " :551 :16 :3"'
def删除符号(文本、符号):
返回“”。连接(映射(lambda x:“如果x在符号中,则为x,否则为x,则为文本))
>>>字符串=“”“'”:621\”:621:1;\“\”:594:25 4 8 0:23\”സര്‍ക്കാര്‍ജീവനക്കാരുടെ ശമ്പളം അറിയാന്‍ ഭാര്യമാരക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍\n:621:40:30;\“\\”:551:16:3“
>>>符号=集合(“[{}&+()”=!.?:../|»:><#«,]1 2 3 4 5 6 7 8 9-+;[])
>>>cleanString=removeSymbols(字符串、符号)
>>>打印(干净字符串)
'" :621 " :621 :1 ;" _ " :594 :25 4 8 0 :23 "സര്\u200dക്കാര്\u200dജീവനക്കാരുടെ ശമ്പളം അറിയാന്\u200dഭാര്യമാര്\u200dക്ക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്\u200d\n:621:4 0 3 0;“”:551:16:3”

我认为您的正则表达式不正确,因为您可以简化它。 例如,子表达式
[{}&+()“=!.?:../|»»:><#«,]
可以简化 在
[!”#&()+,./:?{124;}«»]
中:每个字符只保留一次。 这是因为
[]
用于指示一组字符。 看看Python文档中的“正则表达式操作”一章。 见:

在邮件标题中,您写道:“从大型unicode文本文件中删除符号”, 因此,我认为您有一组要从文件中删除的字符

要简化符号集,可以尝试以下操作:

>>> symbols = "".join(frozenset(r'[{} &+( )" =!.?.:.. / |  » © : >< #  «  ,] 1 2 3 4 5 6 7 8 9 _ - + ; [ ]  %'))
>>> print(symbols)
! #"%&)(+-,/.132547698»:=<?>[];_|©{}«
或者,您可以导入unicode_文字,并删除“u”前缀:

试一试:

import re

symbols = '! #"%&)(+-,/.132547698»:=<?>[];_|©{}«'
regex = "[{0}]+".format(re.escape(symbols))

example = '''" :621 " :621 :1 ;" _ " :594 :25 4 8 0 :23 "സര്‍ക്കാര്‍ജീവനക്കാരുടെ ശമ്പളം അറിയാന്‍ ഭാര്യമാര്‍ക്ക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍
:621 :4 0 3 0 ;" _ " :551 :16 :3 "'''

print(re.sub(regex, "", example, re.UNICODE))
我认为正确的符号集是:
!#“%&”(+-,/.0132547698):=[];124;{}«
。 然后,您可以剥离每一行以删除尾随的空格

因此,此代码段应该适用于您:

import re

symbols = '!#"%&)(+-,/.0132547698»:=<?>[];_|©{}«'
regex = "[{0}]+".format(re.escape(symbols))
sub_symbols = re.compile(regex, re.UNICODE).sub

with open('/home/corpus/All12.txt', 'a') as t:
    with open('/home/corpus/All11.txt', 'r') as n:
        data = n.readline()
        data = sub_symbols("", data).strip()
        t.write(data)
重新导入
符号='!#“%&”(+-,/.0132547698):=[];124;{}«
regex=“[{0}]+.”格式(关于转义(符号))
sub_symbols=re.compile(regex,re.UNICODE).sub
将open('/home/corpus/All12.txt',a')作为t:
将open('/home/corpus/All11.txt',r')作为n:
数据=n.readline()
数据=子符号(“,数据).strip()
t、 写入(数据)

str.translate
可以用来代替
re.sub
。它将Unicode序号映射到替换对,并返回已翻译的字符串。如果替换为
None
则删除字符。
str.maketrans
可用于生成映射

在Python 3中,还记得指定文件的编码。我使用UTF-8进行测试:

#!python3
#coding: utf8
symbols = ' {}&+()"=!.?.:../|»©:><#«,123456789_-+;[]%'
D = str.maketrans('','',symbols)
with open('All12.txt','a',encoding='utf8') as t, open('All11.txt','r',encoding='utf8') as n:
    for line in n:
        t.write(line.translate(D))

参考:,

您是否考虑过对unicode进行解码,例如:

line = line.decode('utf_8')
然后重新编码为……ascii,同时忽略它不知道的字符,例如:

line = line.encode('ascii', 'ignore')
不确定这是否更快或更好。正则表达式的速度很慢,但根据经验我不知道这是否更好。不过这很容易;)

可能是O(2n)复杂度(组合),但长正则表达式可能同样糟糕


更新:正如下面指出的,这是错误的。

你确定代码没有运行吗?可能只是花了很长时间,这可能是因为你正在读取一个2GB的文本文件。尝试在循环中添加一个
打印
。我敢肯定,尝试按chunks@DanielGibbs读取文件。运行一段时间后,它会安静下来。没有lOOP建议你制作一个小样本文件进行测试,否则你会发现很难隔离这个问题。考虑把脚本分成三个函数(读取数据,处理数据,写出数据),这样你就可以单独测试了。你的2个GIB文件中有多少行?如果只有几个(或者一个……),一次迭代一行对您没有多大帮助。此代码删除符号,但使用fp.read()我们试图将整个文件加载到内存中,这对于me@karu,
fp.read()
只是向您展示它对您提供的示例有效。您不必将整个文件加载到内存中。您需要使用
fp=open('file.txt','r')打开文件
然后使用fp:…
中的行的
逐行迭代文件,并在每行上应用regex作为提供的。这不会在内存中加载整个文件,而是一次加载一行。忘记打印
fp.read()
fp.seek(0)
我的代码中的一部分,然后使用其他三行代码
def removeSymbols(text,symbols):
    return "".join(map(lambda x: "" if x in symbols else x,text))

>>> string = '''" :621 \" :621 :1 ;\" _ \" :594 :25 4 8 0 :23 \"സര്‍ക്കാര്‍ജീവനക്കാരുടെ ശമ്പളം അറിയാന്‍ ഭാര്യമാരക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍\n:621 :4 0 3 0 ;\" _ \" :551 :16 :3"'''    

>>> symbols = set('[{} &+( )" =!.?.:.. / |  » © : >< #  «  ,] 1 2 3 4 5 6 7 8 9 _ - + ; [ ]  %')

>>> cleanString = removeSymbols(string,symbols)

>>> print(cleanString)

'" :621 " :621 :1 ;" _ " :594 :25 4 8 0 :23 "സര്\u200dക്കാര്\u200dജീവനക്കാരുടെ ശമ്പളം അറിയാന്\u200d ഭാര്യമാര്\u200dക്ക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്\u200d\n:621 :4 0 3 0 ;" _ " :551 :16 :3"'
>>> symbols = "".join(frozenset(r'[{} &+( )" =!.?.:.. / |  » © : >< #  «  ,] 1 2 3 4 5 6 7 8 9 _ - + ; [ ]  %'))
>>> print(symbols)
! #"%&)(+-,/.132547698»:=<?>[];_|©{}«
symbols = '! #"%&)(+-,/.132547698»:=<?>[];_|©{}«'
# -*- coding: utf8 -*-
symbols = u'! #"%&)(+-,/.132547698»:=<?>[];_|©{}«'
# -*- coding: utf8 -*-
from __future__ import unicode_literals
symbols = '! #"%&)(+-,/.132547698»:=<?>[];_|©{}«'
>>> import re
>>> symbols = '! #"%&)(+-,/.132547698»:=<?>[];_|©{}«'
>>> regex = "[{0}]".format(re.escape(symbols))
>>> print(regex)
[\!\ \#\"\%\&\)\(\+\-\,\/\.132547698\»\:\=\<\?\>\[\]\;\_\|\©\{\}\«]
import re

symbols = '! #"%&)(+-,/.132547698»:=<?>[];_|©{}«'
regex = "[{0}]+".format(re.escape(symbols))

example = '''" :621 " :621 :1 ;" _ " :594 :25 4 8 0 :23 "സര്‍ക്കാര്‍ജീവനക്കാരുടെ ശമ്പളം അറിയാന്‍ ഭാര്യമാര്‍ക്ക് അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍
:621 :4 0 3 0 ;" _ " :551 :16 :3 "'''

print(re.sub(regex, "", example, re.UNICODE))
'''0സര്‍ക്കാര്‍ജീവനക്കാരുടെശമ്പളംഅറിയാന്‍ഭാര്യമാര്‍ക്ക്അവകാശമുണ്ട്വിവരാവകാശകമ്മീഷന്‍
00'''
import re

symbols = '!#"%&)(+-,/.0132547698»:=<?>[];_|©{}«'
regex = "[{0}]+".format(re.escape(symbols))
sub_symbols = re.compile(regex, re.UNICODE).sub

with open('/home/corpus/All12.txt', 'a') as t:
    with open('/home/corpus/All11.txt', 'r') as n:
        data = n.readline()
        data = sub_symbols("", data).strip()
        t.write(data)
#!python3
#coding: utf8
symbols = ' {}&+()"=!.?.:../|»©:><#«,123456789_-+;[]%'
D = str.maketrans('','',symbols)
with open('All12.txt','a',encoding='utf8') as t, open('All11.txt','r',encoding='utf8') as n:
    for line in n:
        t.write(line.translate(D))
#!python3
#coding: utf8
symbols = ' {}&+()"=!.?.:../|»©:><#«,123456789_-+;[]%'
D = str.maketrans('','',symbols)
with open('All12.txt','a',encoding='utf8') as t, open('All11.txt','r',encoding='utf8') as n:
    while True:
        block = n.read(100*1024*1024)
        if not block:
            break
        t.write(block.translate(D))
line = line.decode('utf_8')
line = line.encode('ascii', 'ignore')