我有这个脚本来测试正则表达式以及unicode的行为:
# -*- coding: utf-8 -*-
import re
p = "Solo voy si se sucedierón o se suceden mañana los siguienñes eventos:"
w = re.findall('[a-zA-ZÑñ]+',p.decode('utf-8'), re.UNICODE)
print(w)
print
语句显示了这一点:
[u'Solo', u'voy', u'si', u'se', u'sucedier', u'n', u'o', u'se', u'suceden', u'ma', u'ana', u'los', u'siguien', u'es', u'eventos']
"sucedierón"
正在转变为"u'sucedier', u'n'"
,同样"mañana"
也会变为"u'ma', u'ana'"
。
我尝试过解码,将'\xc3\xb1a'
添加到'Ñ'
在阅读了一些文档后,我意识到使用[a-zA-Z]
只匹配ASCII字符。这就是为什么我必须改为r'\b\w+\b'
所以我可以为正则表达式添加标志
w = re.findall(r'\b\w+\b', p, re.UNICODE)
但这不起作用。
我还先尝试decode()
,然后尝试findall()
:
p = "Solo voy si se sucedierón o se suceden mañana los siguienñes eventos:"
U = p.decode('utf8')
如果我打印变量U
"Solo voy si se sucedierón o se suceden mañana los siguienñes eventos:"
我看到输出是预期的,但是当我再次使用findall()
时:
[u'Solo', u'voy', u'si', u'se', u'sucedier\xf3n', u'o', u'se', u'suceden', u'ma\xf1ana', u'los', u'siguien\xf1es', u'eventos']
现在单词已完成,ó
已替换为\xf3n
,ñ
已替换为\xf1
,unicode值。
我如何findall()
并获取非ASCII字符"ñ","á", "é", "í", "ó", "ú"
我现在有很多这样的问题,相信我,我读了很多,但我找不到丢失的部分。
修改
我正在使用python 2.7
编辑2 别人可以试试@LetzerWille建议的吗?不适合我
答案 0 :(得分:4)
re.UNICODE
flag允许您使用带有变音符号(重音和波浪号)的单词字符\w
和单词边界\b
。这对于匹配不同语言的单词非常有用。
<强>代码:强>
# -*- coding: utf-8 -*-
# http://stackoverflow.com/q/32872917/5290909
#python 2.7.9
import re
text = "Solo voy si se sucedierón o se suceden mañana los siguienñes eventos:"
# Decode to unicode
unicode_text = text.decode('utf8')
matches = re.findall(ur'\b\w+\b', unicode_text, re.UNICODE)
# Encode back again to UTF-8
utf8_matches = [ match.encode('utf-8') for match in matches ]
# Print every word
for utf8_word in utf8_matches:
print utf8_word
答案 1 :(得分:2)
您的代码应写为:
w = re.findall(u'[a-zA-ZÑñ]+', p.decode('utf-8'))
请自行将其他字符添加到角色类中,因为我不知道您要匹配的完整字符集。
处理Unicode文本时,请确保输入字符串和模式都是unicode
1 类型。
1 unicode
逻辑上是一组UTF-16代码单元(在窄版本中)或UTF-32代码单元/代码点(在宽版本中)。如果您打算使用Python处理Unicode文本,为了避免在窄版本中使用星体平面字符的问题,我建议使用Python 3.3及更高版本,或者总是将宽版本用于其他版本。
在Python 2中,str
is simply an array of bytes,因此模式中ASCII范围之外的字符将被简单地解释为在源编码中构成该字符的字节序列:
>>> [i for i in '[a-zA-ZÑñ]+']
['[', 'a', '-', 'z', 'A', '-', 'Z', '\xc3', '\x91', '\xc3', '\xb1', ']', '+']
在编译re.DEBUG
和str
对象时比较unicode
的输出:
>>> re.compile('[a-zA-ZÑñ]+', re.DEBUG)
max_repeat 1 4294967295
in
range (97, 122)
range (65, 90)
literal 195 # \xc3
literal 145 # \x91
literal 195
literal 177
<_sre.SRE_Pattern object at 0x6fffffd0dd8>
>>> re.compile(u'[a-zA-ZÑñ]+', re.DEBUG)
max_repeat 1 4294967295
in
range (97, 122)
range (65, 90)
literal 209 # Ñ
literal 241 # ñ
<_sre.SRE_Pattern object at 0x6ffffded030>
由于您未使用\s
,\w
,\d
,re.UNICODE
标志无效且可以删除。
答案 2 :(得分:0)
它对我有用。我使用Pycharm并将控制台设置为utf-8。
您需要将输出控制台配置为utf-8 ....
p = "Solo voy si se sucedierón o se suceden mañana los siguienñes eventos:"
w = re.findall('ñ',p, re.UNICODE)
print(w)
['ñ', 'ñ']
w = re.findall('[a-zA-ZÑñó:]+',p, re.UNICODE)
print(w)
['Solo', 'voy', 'si', 'se', 'sucedierón', 'o', 'se', 'suceden', 'mañana', 'los', 'siguienñes', 'eventos:']