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])
也不可能。
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}
我也喜欢这个,因为它更通用,即捕获允许具有不同长度的标识符(例如,10CG80M10GHJ)(尽管这在我的情况下不需要,但也许我将来需要这样做) – user3182532
这是一个很好的解决方案,谢谢!但是我仍然很好奇为什么我的工作不行......? – user3182532
参考此[回复](http://stackoverflow.com/a/23782359/3451543):Python re模块,因为大多数语言(具有.NET的显着例外),不支持可变长度lookbehind。 – mrorno
有关您的解决方案的问题:如果我说myregex = re.compile(“[0-9] + [MIDNSHP = X]”),为什么它不再工作,并将其作为re.findall的第一个参数? – user3182532