Python - 正则表达式 - 特殊字符和ñ

时间:2015-09-30 18:08:20

标签: python regex unicode

我有这个脚本来测试正则表达式以及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建议的吗?不适合我

3 个答案:

答案 0 :(得分:4)

带有Python中重音字符(变音符号)的正则表达式

re.UNICODE flag允许您使用带有变音符号(重音和波浪号)的单词字符\w和单词边界\b。这对于匹配不同语言的单词非常有用。

  1. 将您的文字从UTF-8解码为
  2. 确保将模式和主题文本作为传递给正则表达式函数。
  3. 结果是一个字节数组,可以循环/映射以再次编码回UTF-8
  4. 打印阵列显示非ASCII字节转义,但可以安全地单独打印每个字符串。
  5. <强>代码:

    # -*- 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
    

    ideone Demo

答案 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.DEBUGstr对象时比较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\dre.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:']