Python的正则表达式:回顾后先行+与字符集

问题描述:

我想获得字符串10M5D8P成词典:Python的正则表达式:回顾后先行+与字符集

L:10,d:5,P:8等等...

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

作为第一步,我希望将字符串拆分为lookbehead和lookahead,在两种情况下匹配此正则表达式:[0- 9] + [MIDNSHP = X]

所以我不工作的解决方案看起来像这样此刻:

import re

re.compile(“(? (?= [0-9] + [MIDNSHP = X])“)。split(”10M5D8P“)

它给我一个错误消息,不明白:“回顾后需要固定宽度模式”

您可以使用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模块不支持可变长度后向断言。而且它也不支持在零宽边界上分割,所以这个(?<=\d)(?=[A-Z])也不可能。

+0

这是一个很好的解决方案,谢谢!但是我仍然很好奇为什么我的工作不行......? – user3182532

+0

参考此[回复](http://stackoverflow.com/a/23782359/3451543):Python re模块,因为大多数语言(具有.NET的显着例外),不支持可变长度lookbehind。 – mrorno

+0

有关您的解决方案的问题:如果我说myregex = re.compile(“[0-9] + [MIDNSHP = X]”),为什么它不再工作,并将其作为re.findall的第一个参数? – user3182532

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

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

这仅使用单个字符作为回顾后和一位数字为超前。但是,如果您尝试使用split这个表达式,它将因Python bug 3262而失败。你需要使用这样的替代方法:

>>> 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} 
+0

我也喜欢这个,因为它更通用,即捕获允许具有不同长度的标识符(例如,10CG80M10GHJ)(尽管这在我的情况下不需要,但也许我将来需要这样做) – user3182532