我正在尝试使用正则表达式模块中的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)。任何帮助是极大的赞赏。我已经玩了一段时间了。
答案 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"