我正在研究一个用给定规则翻译给定文本的函数。
def bork(text):
"""
Implementation of language transformation based on Swedish-Chef talk.
"""
rules = {"\be": "i",
"the": "zee",
"\Be\b": "e-a",
"an": "un"
}
rules = dict((re.escape(k), v) for k, v in rules.items())
pattern = re.compile("|".join(rules.keys()))
borked = pattern.sub(lambda i: rules[re.escape(i.group(0))], text.strip())
return borked
text = """experienced"""
print bork(text)
# gives "experienced"
它应该给"ixperienced"
。由于规则\be: i
。其他转换在使用较大输入进行测试时效果很好,但是这个失败了,请帮助我。
修改:我添加了规则"\Bi\B": "ee"
。哪个应该得到结果"ixpereeenced"
。这也没有用。我仍然得到"experienced"
。
Edit2:似乎问题存在于我使用反斜杠的规则中,但是,我尝试使用原始字符串和re.escape()
。之后,我尝试删除re.escape()
,但这在字典调用中给出了一个关键错误。(我也想知道为什么会发生这种情况)
答案 0 :(得分:3)
"\b"
是退格字符,ASCII值为8. r"\b"
是文字字符\
和b
。使用原始字符串来防止解释转义序列。
rules = {
r"\be": "i",
r"the": "zee",
r"\Be\b": "e-a",
r"an": "un"
}
然后,摆脱第一个re.escape()
电话。
答案 1 :(得分:3)
re.sub的一次传递,使用捕获组,以便我们可以确定在相关区域上匹配的模式。您可以通过保留模式列表来简化subst
函数的逻辑,而不是每次都必须枚举rules
字典......
rules = {
r'(\be)' : 'i',
r'(the)' : 'zee',
r'(an)' : 'un',
r'(\Be\b)' : 'e-a'
}
pattern = '|'.join(rules.iterkeys())
def subst(matchobj):
dind = [ind for (ind, val) in enumerate(matchobj.groups()) if val is not None][0]
return rules[[val for (ind, val) in enumerate(rules) if ind == dind][0]]
text = 'experienced'
re.sub(pattern, subst, text)
答案 2 :(得分:1)
正则表达式组的顺序很重要。使用“|”时,即使后者在列表中有较长的匹配,也会接受第一个匹配。因此,您不应该依赖dict.keys()
,因为订单未定义。使用列表(我想你可以使用有序字典)。此外,matchobject.lastindex
返回最后(或唯一)匹配组的索引。
rules = [
(r'\be' , 'i' ),
(r'the' , 'zee'),
(r'an' , 'un' ),
(r'\Bi\B', 'ee' ),
(r'\Be\b', 'e-a' )
]
pattern = '|'.join('({})'.format(rule[0]) for rule in rules)
def subst(matchobj):
#print(matchobj)
return rules[matchobj.lastindex-1][1]
text = 'experienced'
re.sub(pattern, subst, text)
返回:
'ixpereeenced'