我有一个字符串:
string = u'11a2ee22b333c44d5e66e777e8888'
我想找到所有k
个连续的数字块n <= k <= m
。
仅使用正则表达式:
比方说n=2
和m=3
使用(?:\D|^)(\d{2,3})(?:\D|$)
re.findall(u'(?:\D|^)(\d{2,3})(?:\D|$)',u'11a2ee22b333c44d5e66e777e8888')
给出这个输出:
['11', '333', '66']
期望的输出:
['11', '22', '333', '44', '66', '777']
我知道有其他解决方案,如:
filter(lambda x: re.match('^\d{2,3}$', x), re.split(u'\D',r'11a2ee22b333c44d5e66e777e8888'))
给出了所需的输出,但我想知道第一种方法有什么问题?
似乎re.findall
按顺序排列并在匹配时跳过上一部分,那么可以做些什么呢?
答案 0 :(得分:2)
注意:您在问题中显示的结果不是我得到的结果:
>>> import re
>>> re.findall(u'(?:\D|^)(\d{2,3})(?:\D|$)',u'11a2ee22b333c44d5e66e777e8888')
[u'11', u'22', u'44', u'66']
它仍然缺少你想要的一些比赛,但不是相同的。
问题在于,即使像(?:\D|^)
和(?:\D|$)
这样的非捕获群体没有捕获他们匹配的内容,他们仍然消费 it。
这意味着产生'22'
的匹配实际消耗了:
e
,(?:\D|^)
- 未捕获(但仍被消费)22
与(\d{2,3})
- 已捕获b
与(?:\D|$)
- 未捕获(但仍被消费) ...以便b
之前无法再匹配333
。
您可以通过lookbehind和lookahead语法获得所需的结果:
>>> re.findall(u'(?<!\d)\d{2,3}(?!\d)',u'11a2ee22b333c44d5e66e777e8888')
[u'11', u'22', u'333', u'44', u'66', u'777']
在这里,(?<!\d)
是一个负面的背后,检查匹配前面没有数字,(?!\d)
是一个负前瞻,检查匹配后面没有数字。至关重要的是,这些结构不会消耗任何字符串。
各种前瞻和后视构造在中描述
Python re
文档的Regular Expression Syntax部分。
答案 1 :(得分:1)
环视正则表达式,\ d {2,3}表示2位或3位数,(?= [a-z])表示数字后面的字母。
In [136]: re.findall(r'(\d{2,3})(?=[a-z])',string)
Out[136]: ['11', '22', '333', '44', '66', '777']
答案 2 :(得分:1)
你甚至可以用一个函数来概括它:
afterrender: function() {
Ext.fly('div').createChild({
tag: 'div',
html: "<label class='highlight'> Try the new <a href='#'>Beta version</a><span class='icon-clear'></span></label>"
}).on("click", function(e) {
if (e.target is <a>) {
//do some fun
}else if (e.target is <span>) {
//do some func
}
}, this, { delegate: 'label' });
}