我有一个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序列。
答案 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))