给定一个用 UTF-8 编码并由 unicodeNFC
规范化的法语 (>200GB( 大型文本文件,我想使用 Python 或 Bash 或任何更快的方法删除除重音/非重音字母、数字和标点符号之外的所有特殊字符。以前,我通过扫描文本来手动执行此任务,以确定是否有任何我不想要的特殊字符,并使用如下所示的字符代码将其删除:
def remove_special_chars(text):
text = re.sub(chr(65533), '', text)
text = re.sub(chr(9658), '', text)
text = re.sub(chr(9660), '', text)
text = re.sub(chr(169), '', text)
return text
(字符代码 65533( ► (字符代码 9658( ▼ (字符代码 9660( (字符代码 169( © 等
但是,对于大型文本文件,不可能再以这种方式执行此操作。因此,我正在考虑通过检查字符是否是(重音/非重音(字母或数字或标点符号来删除所有特殊字符,如果不是,则删除。我尝试了以下内容,但命令行未执行。
grep -P -v '[^a-zA-Z0-9 àâäèéêëîïôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ!"#$%&'()*+,\-./:;<=>?@[]^_`{|}~]' file
你能帮我解决这个问题吗?提前感谢您的帮助!
要删除的所有字符都属于"符号,其他Unicode"类别。
在 Python 中,你可以安装 PyPi 正则表达式模块,添加
import regex
然后像这样更改内容:
text = regex.sub(r'p{So}+', '', text)
在Linux中,你可以使用Perl单行代码来做到这一点:
perl -i -CSD -Mutf8 -pe 's/p{So}+//g' file
-i
选项将内联修改文件,-CSD -Mutf8
存在,因为我相信您的文件采用 UTF8 编码。
我假设您的文本使用的是法语加拿大语的代码页,该代码页cp863
.您可以在不使用正则表达式的情况下使用的一种"黑客"方法如下。
# this ignores any characters that are not in the standard french character page
text = "abcdeefghijkàâäèéêëîïôœùûüÿçÀÂÄÈÉÊËÎÏÔ►�▼©".encode("cp863", "ignore")
print(text.decode('cp863'))
# outputs
abcdeefghijkàâèéêëîïôùûüçÀÂÈÉÊËÎÏÔ
我会使用unicodedata
模块,这是一个标准模块,所以它应该已经在你的系统中了。
您应该使用unicodedata.category(
chr
)
循环每个字符,并选中要保留或丢弃的类别。
Unicode 发布常规类别值:https://www.unicode.org/reports/tr44/tr44-6.html#General_Category_Values
我会保留L*
(字母(,N*
(数字(,P*
(标点符号(和Zs
(空格(。我会将其他Z*
更改为空格,也会将其他字符更改为空格,但也会将该行保存到文件中,以检查是否需要调整规则。
注意:您还可以限制/转换其他代码(例如,将左括号转换为普通括号等(对您的使用进行编码。
注意:上述建议还将删除$
(货币符号(,您可以对其进行调整。