Python正则表达式:Lookbehind + Lookahead with characterset

时间:2015-07-20 04:27:41

标签: python regex lookahead lookbehind

我想将字符串10M5D8P放入字典中:

M:10,D:5,P:8等......

字符串可能更长,但它始终是一个数字后跟此字母表中的单个字母:MIDNSHP = X

作为第一步,我想用一个lookbehind和lookahead来分割字符串,在两种情况下匹配这个正则表达式:[0-9] + [MIDNSHP = X]

所以我的工作解决方案目前看起来像这样:

导入重新

re.compile( “?(小于?= [0-9] + [MIDNSHP = X])(= [0-9] + [MIDNSHP = X])”)。分裂( “10M5D8P”)< / p>

它给了我一条我不明白的错误信息:“后视需要固定宽度模式”

2 个答案:

答案 0 :(得分:2)

您可以使用re.findall。

>>> import re
>>> s = "10M5D8P"
>>> {i[-1]:i[:-1] for i in re.findall(r'[0-9]+[MIDNSHP=X]', s)}
{'M': '10', 'P': '8', 'D': '5'}
>>> {i[-1]:int(i[:-1]) for i in re.findall(r'[0-9]+[MIDNSHP=X]', s)}
{'M': 10, 'P': 8, 'D': 5}

你的正则表达式不起作用,因为re模块不支持可变长度的lookbehind断言。并且它也不支持在零宽度边界上进行拆分,因此(?<=\d)(?=[A-Z])也是不可能的。

答案 1 :(得分:2)

look-behind requires fixed-width pattern正是它所说的 - 一个后视模式必须匹配Python引擎中固定数量的字符。特别是,不允许包含任何量词(?+*)。因此,我们应该选择一个固定宽度的作品作为我们的外观:

(?<=[MIDNSHP=X])(?=\d)

这只使用单个字符作为lookbehind,使用单个数字作为前瞻。但是,如果您尝试split使用此表达式,则会因 example而失败。您需要使用这样的解决方法:

>>> re.compile(r"(?<=[MIDNSHP=X])(?=\d)").sub('|', '10M5D8P').split("|")
['10M', '5D', '8P']

但这非常难看。一个更简单的解决方案是使用findall 提取您想要的内容

>>> re.findall('([0-9]+)([MIDNSHP=X])', '10M5D8P')
[('10', 'M'), ('5', 'D'), ('8', 'P')]

您可以从中轻松创建字典:

>>> {k:int(v) for v,k in re.findall('([0-9]+)([MIDNSHP=X])', '10M5D8P')}
{'P': 8, 'M': 10, 'D': 5}