说,我有'ABBACDA',我想找到每个A的位置索引。
在Python中使用Regex,
match = re.findall('A', 'ABBACDA')
只返回一个列表。
我可以调整这个吗?或者我应该走一条完全不同的路线?我想避免使用for x in enumerate(str)
,因为我还想检查“BB”的位置以及从哪个索引开始。
答案 0 :(得分:5)
示例1:
match = re.finditer('A', 'ABBACDA')
for m in match:
print m.start(), m.end(), m.group(0)
输出:
0 1 A
3 4 A
6 7 A
示例2:
match = re.finditer('BB', 'ABBACDA')
for m in match:
print m.start(), m.end(), m.group(0)
输出:
1 3 BB
答案 1 :(得分:2)
致John Machin
«(1)在你的“查找”代码中,tof是“A”,在你的正则代码中,tof是“BB”»
没有。 有一个'find'代码,其中tof ='A', 并且有一个代码将'find'方法和'regex'方法与tof ='BB'进行比较。没有单独的'正则表达式'代码,tof ='BB'
'find'代码以一种孤立的方式呈现这个解决方案,以便更清楚,因为在第二个代码中,它的可见性是不可见的。
我将pat = re.compile(tof)的定义放在循环之外,以便不计算在测量时间内创建它的时间。正如它在第二个代码的开头,你相信它是一个完全'正则表达式'的代码。事实并非如此。这是一个比较代码。
你应该仔细阅读。
«(2)ch [prec:]。find(tof)而不是ch.find(tof,prec)»
是
实际上我已经知道索引必须放在find()中而不是在字符串中使用。我发现它并且我已经在过去的代码中使用过那种方式,但我脑子里只有一个空白。
顺便说一下,代码更简单。其次,正如您所指出的,更正的“查找”解决方案现在运行得更快。当正则表达式解决方案在0.77 * T(校正前0.65 * T)运行时,它在T秒内运行:
ch = 'jggBBjgjBBBjhgBBBBjjgBBBBBjjggBBBBBBjjjgjBBBBBBB'
tof = 'BB'
L = len(tof)
X,Y = [],[]
pat = re.compile(tof)
for essay in xrange(5):
te = clock()
for i in xrange(1000):
li = []
x = ch.find(tof)
while x+1:
li.append(x)
x = ch.find(tof,x+L)
X.append( clock()-te )
te = clock()
for i in xrange(1000):
ly = [ m.start() for m in pat.finditer(ch) ]
Y.append( clock()-te )
print li,'\n',ly,'\n'
print min(X),'\n',min(Y)
但它并没有那么显着的加速:快18%。
«(3)你的查找代码考虑重叠匹配,正则表达式代码没有»
我不这么认为。我正是用“ABBACDABBmmrteyBBgfrewBBBBBioBByt BBB ggddbBB BBbGtBBBGtbBbGT”包含“BBBBB”试图验证“发现”解决方案给出了相同的结果为“正则表达式”的解决方案,因为我知道,正则表达式不会返回重叠的匹配。我精确地使用L = len(tof)来避免检测重叠切片。
上述代码的结果:
[3, 8, 14, 16, 21, 23, 30, 32, 34, 41, 43, 45]
[3, 8, 14, 16, 21, 23, 30, 32, 34, 41, 43, 45]
那么“您的查找代码是否考虑重叠匹配”是什么意思?拜托,
«(4)等等»
这是不公平的。如果有etceterae,告诉哪些。如果没有......好吧,我不知道...
我认为1:1的比率对假的,一个可疑一个和一个不公平的一个右评论是不够的downvote。
此外,在我看来,写上的问题后1〜2小时,让不完美的答案,不逃避downvotes,而良好的相似者更很少upvoted因为questionner有他的解决方案很长一段时间
答案 2 :(得分:0)
如果您只查找一个结果,请改用re.search函数。 返回MatchObject(http://docs.python.org/library/re.html#re.MatchObject)。该对象具有start()和end()函数。
答案 3 :(得分:0)
您可以尝试对以下内容进行计时,看它是否比正则表达式更快:
def multifind(needle, haystack, overlap=False):
delta = 1 if overlap else max(1, len(needle))
pos = 0
find = haystack.find
while 1:
pos = find(needle, pos)
if pos < 0: return
yield pos
pos += delta
>>> data = 'ABBACDABBmmrteyBBgfrewBBBBBioBBytA BBB ggdAdbBB BBbGtBBABGtbBbGT'
>>> list(multifind('A', data))
[0, 3, 6, 33, 42, 55]
>>> list(multifind('BB', data))
[1, 7, 15, 22, 24, 29, 35, 45, 48, 53]
>>> list(multifind('BB', data, overlap=True))
[1, 7, 15, 22, 23, 24, 25, 29, 35, 36, 45, 48, 53]
>>> list(multifind('', 'qwerty'))
[0, 1, 2, 3, 4, 5, 6]
>>>
答案 4 :(得分:0)
哦,我也知道使用发电机,我忘记了它在这项研究中的优势。这是一个很好的评论,这个。
使用别名hayfind = haystack.find来提高代码速度也非常棘手。
现在'find with generator'方法在T中运行,'regex'方法仅在0.96 * T
运行ch = 'jggBBjgjBBBjhgBBBBjjgBBBBBjjggBBBBBBjjjgjBBBBBBB'
tof = 'BB'
L = len(tof)
X,Y = [],[]
pat = re.compile(tof)
def multifind(needle, haystack):
delta = len(needle)
pos = 0
hayfind = haystack.find
while 1:
pos = hayfind(needle, pos)
if pos < 0: return
yield pos
pos += delta
for essay in xrange(20):
te = clock()
for i in xrange(10000):
li = list(multifind(tof,ch))
X.append( clock()-te )
te = clock()
for i in xrange(10000):
ly = [ m.start() for m in pat.finditer(ch) ]
Y.append( clock()-te )
print li,'\n',ly,'\n'
print min(X),'\n',min(Y)
这两种方法具有相同的速度。但我最终更喜欢'正则表达式'解决方案,因为它可以被修改以在需要时获得更多结果(开始和结束,其他条件......),而'find'解决方案只给出位置。
答案 5 :(得分:-1)
我喜欢正则表达式,但我搜索了另一种解决方案:
ch = 'ABBACDABBmmrteyBBgfrewBBBBBioBBytA BBB ggdAdbBB BBbGtBBABGtbBbGT'
tof = 'A'
li, prec = [], 0
x = ch[prec:].find(tof)
while x+1:
li.append(prec+x)
prec += x+1
x = ch[prec:].find(tof)
print li
结果
[0, 3, 6, 33, 42, 55]
我测量了速度,当使用find()的解决方案在T秒内运行时,使用正则表达式的解决方案在0,65 * T运行时我感到很惊讶:
ch = 'ABBACDABBmmrteyBBgfrewBBBBBioBByt BBB ggddbBB BBbGtBBBGtbBbGT'
tof = 'BB'
X,Y = [],[]
pat = re.compile(tof)
for essay in xrange(50):
te = clock()
for i in xrange(1000):
li, prec, L = [], 0, len(tof)
x = ch[prec:].find(tof)
while x+1:
li.append(prec+x)
prec += x+L
x = ch[prec:].find(tof)
X.append( clock()-te )
te = clock()
for i in xrange(1000):
ly = [ m.start() for m in pat.finditer(ch) ]
Y.append( clock()-te )
print li
print ly
print
print min(X)
print min(Y)