我正在尝试识别和替换字符串中的unicode字符,我正在处理这些字符串以制作关键字匹配过滤器。
例如,给定字符串
"Apple iPhone 12 mini A2176 128GBu00a0(PRODUCT) Red!u00a0Perfect condition! Unlocked!"
我希望当我使用resub函数(用空格"代替模式(时的输出是
"Apple iPhone 12 mini A2176 128GB (PRODUCT) Red! Perfect condition! Unlocked!"
所以我去了一个regex构建和测试网站,想出了这个模式
\u[a-z|0-9]{4}
它捕获2个unicode字符串
u00a0 and u00a0
现在,为了将它应用于我的python代码,我首先尝试了这个片段。在这里,我使用findall
函数来查看代码是否会返回unicode字符串
import re
strin = "Apple iPhone 12 mini A2176 128GBu00a0(PRODUCT) Red!u00a0Perfect condition! Unlocked!"
print(re.findall('\u[a-z|0-9]{4}', strin))
导致以下错误返回
re.error: incomplete escape u at position 0
然后我尝试在字符串模式前面添加一个"r"。没有出现错误,但没有返回unicode字符串
print(re.findall(r'\u[a-z|0-9]{4}', strin))
输出为空列表[]
然后我尝试了同样的2种方法,但只有1个反斜杠
print(re.findall('u[a-z|0-9]{4}', strin))
给出SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: truncated uXXXX escape
print(re.findall(r'u[a-z|0-9]{4}', strin)) gives
re.error: incomplete escape u at position 0
您在这里有多个误解(所有这些都是常见的常见问题解答(。
re.findall
的参数是一个字符串。在Python中,字符串中的反斜杠必须通过加倍来转义。一个更好的解决方案是使用r"..."
原始字符串表示法,尤其是对于正则表达式,它通常需要包含实际正则表达式的字面反斜杠。
从findall
获得的错误消息告诉您字符转义u[
不正确,因为[
不是十六进制数。(事实上,即使您的正则表达式在语法上没有错误,它也太匹配了;Python中Unicode字符转义的正则表达式应该是\u[0-9a-f]{4}
,而不是a-z
。(
字符u00a0
是单个Unicode字形,在字符串中包含单个字符。你不能用这样的正则表达式来匹配它。可以匹配的是例如
re.findall(r'[u0080-uffef]', strin)
它包含一个字符类,覆盖Unicode基本多语言平面中的非ASCII字符范围(包括代理,正确地说,我们应该排除它,但我们不要去问初学者的问题。也许还需要注意的是,BMP之外还有Unicode字符,可以与[U00010000-U0010FFFF]
匹配(。
(顺便注意,字符类[a-z|0-9]
包括字符类中的文字字符|
。|
代表字符类之外的交替,但在[
…]
中,除了初始^
和-
之外的所有字符都只是文字字符。(
但更根本的是,初学者对";我不懂Unicode的东西"是错误的;响应应该是"0";我需要理解这些东西";,而不是";我需要把它去掉";。很少有简单地删除所有Unicode的好例子,而且这种趋势只会把你拖回到Unicode之前的黑暗时代,那时你只能在西方计算机中表示英语文本(而且几乎不能这样(。
这个特定问题的一个更原则的解决方案是将所有空白字符(可能除了制表符(规范化为ASCII空间,并在遇到其他Unicode字符时找出如何处理它们。什么是合理的在很大程度上取决于您的具体应用程序。对于搜索或NLP,规范化或";"压平";所有文本都转换为接近ASCII的子集,但对于许多其他应用程序,您通常需要更细致的内容。
解决了这个问题,试试
Python 3.8.2 (default, May 18 2021, 11:47:11)
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> strin = "Apple iPhone 12 mini A2176 128GBu00a0(PRODUCT) Red!u00a0Perfect condition! Unlocked!"
>>> import re
>>> re.sub(r's', ' ', strin)
'Apple iPhone 12 mini A2176 128GB (PRODUCT) Red! Perfect condition! Unlocked!'
如果您的目的只是从文本中删除unicode,那么您的工作太辛苦了。你可以用做得很简单
strin.encode('ascii', 'ignore').decode('ascii')
您将字符串编码为ascii并忽略错误,然后再次将其解码为ascii,从而删除所有非ascii字符