来自正则表达式模块的Python 2.5子函数无法识别模式

时间:2013-11-21 05:24:17

标签: python regex unicode python-2.5

我正在尝试使用正则表达式模块中的Python子函数来识别和更改字符串中的模式。以下是我的代码。

old_string = "afdëhë:dfp"
newString = re.sub(ur'([aeiouäëöüáéíóúàèìò]|ù:|e:|i:|o:|u:|ä:|ë:|ö:|ü:|á:|é:|í:|ó:|ú:|à:|è:|ì:|ò:|ù:)h([aeiouäëöüáéíóúàèìòù])', ur'\1\2', old_string)

所以我应该在应用代码后得到的是afdëë:dfp(没有h)。所以我试图匹配一个元音(有时带有重音,有时带有一个冒号),然后是另一个元音(有时带有重音符号)。所以举几个例子......

ò:ha becomes ò:a
ä:hà becomes ä:hà
aha becomes aa
üha becomes üa
ëhë becomes ëë

所以我试图在两个元音之间移除h,并且当它跟随一个带有冒号的音量之后移除h然后是另一个元音(即a:ha)。任何帮助是极大的赞赏。我已经玩了一段时间了。

2 个答案:

答案 0 :(得分:3)

单个用户感知的字符可能包含多个Unicode代码点。这样的字符可能会破坏u'[abc]' - 就像在Python中只看到代码点的正则表达式一样。要解决此问题,您可以使用u'(?:a|b|c)'正则表达式。另外,不要混用字节和Unicode字符串,即old_string也应该是Unicode。

应用最后一条规则会修复您的示例。

您可以使用lookahead / lookbehind断言编写正则表达式:

# -*- coding: utf-8 -*-
import re
from functools import partial

old_string = u"""
  ò:ha becomes ò:a
  ä:hà becomes ä:à
  aha becomes aa
  üha becomes üa
  ëhë becomes ëë"""

# (?<=a|b|c)(:?)h(?=a|b|c)
chars = u"a e i o u ä ë ö ü á é í ó ú à è ì ò".split()
pattern = u"(?<=%(vowels)s)(:?)h(?=%(vowels)s)" % dict(vowels=u"|".join(chars))
remove_h = partial(re.compile(pattern).sub, ur'\1')
# remove 'h' followed and preceded by vowels
print(remove_h(old_string))

输出

  ò:a becomes ò:a
  ä:à becomes ä:à
  aa becomes aa
  üa becomes üa
  ëë becomes ëë

为了完整起见,您还可以使用unicodedata.normalize() function规范化程序中的所有Unicode字符串(请参阅文档中的示例,以了解您可能需要它的原因)。

答案 1 :(得分:0)

这是编码问题。对于不同的pythons,文件编码和old_string的非unicode的不同组合表现不同。

例如,你的代码适用于2.6到2.7的python(下面的所有数据都是cp1252编码):

# -*- coding: cp1252 -*-
old_string = "afdëhë:dfp"

但如果文件中没有指定编码,则SyntaxError: Non-ASCII character '\xeb'失败。

然而,对于使用

的python 2.5,这些行失败了
`UnicodeDecodeError: 'ascii' codec can't decode byte 0xeb in position 0: ordinal not in range(128)` for python 2.5

虽然所有pythons都无法删除带有old_string为非unicode的h

# -*- coding: utf8 -*-
old_string = "afdëhë:dfp"

所以你必须提供正确的编码定义old_unicode也是unicode字符串,例如这个会做:

# -*- coding: cp1252 -*-
old_string = u"afdëhë:dfp"