正则表达式中的python unicode字符串

时间:2018-05-07 15:42:08

标签: python regex unicode

我有一个unicode编码(带BOM)源文件和一些包含unicode符号的字符串。 我想用下划线替换所有不属于已定义字符集的字符。

#  coding: utf-8 
import os
import sys
import re

t = " [°]    \n  € dsf $ ¬ 1 Ä 2 t3¥4Ú";
print re.sub(r'[^A-Za-z0-9 !#%&()*+,-./:;<=>?[\]^_{|}~"\'\\]', '_', t, flags=re.UNICODE)

output:     ____ [__]    _  ___ dsf _ __ 1 __ 2 t3__4__
expected:   _ [_]    _  _ dsf _ _ 1 _ 2 t3_4_

但每个字符都被一些下划线替换,这些下划线可能等于其unicode表示中的字节。

可能还有一个问题:

在实际问题中,字符串是由另一个python模块从unicode文件中读取的,我不知道它是否正确处理了unicodeness。因此字符串变量可能标记为ascii但包含unicode序列。

2 个答案:

答案 0 :(得分:3)

对Unicode字符串进行操作,而不是字节字符串。您的源编码为UTF-8,因此字符编码为每个字节一到四个字节。解码为Unicode字符串或使用Unicode常量将有所帮助。代码似乎也是基于Python 2的,因此在狭窄的Python 2版本(Windows上的默认版本)上,您仍然会遇到问题。如果您使用两个或更多Unicode代码点构建字形,也可能会出现问题:

#  coding: utf-8 
import re

t = u" [°]    \n  € dsf $ ¬ 1 Ä 2 t3¥4Ú";
print re.sub(ur'[^A-Za-z0-9 !#%&()*+,-./:;<=>?[\]^_{|}~"\'\\]', '_', t, flags=re.UNICODE)

输出(在Windows Python 2.7窄版本上):

__ [_]    _  _ dsf _ _ 1 _ 2 t3_4_

注意第一个表情符号仍然有双下划线。大于U + FFFF的Unicode字符被编码为代理对。这可以通过显式检查它们来处理。代理对的第一个代码点是U + D800到U + DBFF,第二个是U + DC00到U + DFFF:

#  coding: utf-8 
import re

t = u" [°]    \n  € dsf $ ¬ 1 Ä 2 t3¥4Ú";
print re.sub(ur'[\ud800-\udbff][\udc00-\udfff]|[^A-Za-z0-9 !#%&()*+,-./:;<=>?[\]^_{|}~"\'\\]', '_', t, flags=re.UNICODE)

输出:

_ [_]    _  _ dsf _ _ 1 _ 2 t3_4_

但是你仍然会遇到复杂表情符号的问题:

#  coding: utf-8 
import re

t = u"‍‍‍";
print re.sub(ur'[\ud800-\udbff][\udc00-\udfff]|[^A-Za-z0-9 !#%&()*+,-./:;<=>?[\]^_{|}~"\'\\]', '_', t, flags=re.UNICODE)

输出:

___________

答案 1 :(得分:-1)

怎么样:

print(re.sub(r'[^A-Öa-ö0-9 !#%&()*+,-./:;<=>?[\]^_{|}~"\'\\]', '_', t))