在另一个字符串中多次查找字符串-Python
我正在尝试使用Python的预定义函数(如find和index)查看一个字符串是否存在于另一个字符串中 现在,我的函数使用两个字符串作为参数,一个是我们要搜索的字符串,另一个字符串是我们在第一个字符串中要查找的字符串 如果第一个字符串中存在第二个字符串,我希望我的函数返回它在第一个字符串中出现的所有位置 现在,我的函数能够找到第一个匹配项并返回索引,但是我希望找到多个匹配项,而不仅仅是第一个 下面是我的代码:在另一个字符串中多次查找字符串-Python,python,string,python-3.x,Python,String,Python 3.x,我正在尝试使用Python的预定义函数(如find和index)查看一个字符串是否存在于另一个字符串中 现在,我的函数使用两个字符串作为参数,一个是我们要搜索的字符串,另一个字符串是我们在第一个字符串中要查找的字符串 如果第一个字符串中存在第二个字符串,我希望我的函数返回它在第一个字符串中出现的所有位置 现在,我的函数能够找到第一个匹配项并返回索引,但是我希望找到多个匹配项,而不仅仅是第一个 下面是我的代码: def multi_find (s, r): s_len = len(s)
def multi_find (s, r):
s_len = len(s)
r_len = len(r)
if s_len < r_len:
n = -1
else:
m = s_len - r_len
n = -1 # assume r is not yet found in s
i = 0
while n == -1 and i < m:
# search for r in s until not enough characters are left
if s[i:i + r_len] == r:
n = i
else:
i = i + 1
print (n)
multi_find("abcdefabc. asdli! ndsf acba saa abe?", "abc")
def多重查找(s,r):
s_len=len(s)
r_len=len(r)
如果s_len
现在,这将只输出“0”,因为abc首先出现在这里。。如何让它返回“0”和“6”(第二次出现的开始),基本上在找到一个后继续检查
我想创建一个列表,列出所有发生的地方,然后将我添加到该列表中,但当我尝试这样做时,没有任何效果。您可以:
>>> haystack = "abcdefabc. asdli! ndsf acba saa abe?"
>>> needle = "abc"
>>> for i, _ in enumerate(haystack):
... if haystack[i:i + len(needle)] == needle:
... print (i)
...
0
6
def多重查找(s,r):
s_len=len(s)
r_len=len(r)
_完成=[]
如果s_len
使用regex的另一种选择:
>>> import re
>>> haystack = "abcdefabc. asdli! ndsf acba saa abe?"
>>> needle = "abc"
>>> [m.start() for m in re.finditer(r'{}'.format(re.escape(needle)), haystack)]
[0, 6]
上述解决方案不适用于重叠的子字符串,如'aaaa'
中有3'aa'
。因此,如果您也想找到重叠的匹配,那么:
>>> haystack = "bobob"
>>> needle = "bob"
>>> [m.start() for m in re.finditer(r'(?={})'.format(re.escape(needle)), haystack)]
[0, 2]
def多重查找(s,r):
s_len=len(s)
r_len=len(r)
n=[]#假设在s中尚未找到r
如果s_len>=r_len:
m=s_len-r_len
i=0
而我
基本上就是用一个列表替换n,这样您就可以在找到值时继续向其中添加值。您还需要增加i,即使找到匹配项,它也会永远卡在循环中,除非您有while n==-1约束,该约束使它在找到匹配项后立即停止。最好的方法可能是继续调用find函数(这也是最快的)
输出:
[6, 10]
注意:我认为这个答案仍然是一个很好的“教学答案”,我已经在这个线程的其他地方提交了一个更好的解决方案,没有递归
这允许您通过一个可选的start
位置,在s
中开始搜索
这个解决方案是递归的,它可能是最快的实现,也可能不是最快的实现,但它是正确的,我相信它可以让代码很容易地在s
的每个位置识别三种可能性中的每一种:
s
找到另一个r
没有找到另一个r
@雅各布,我希望你会发现这本书很短,但仍然很容易理解
def multi_find(s, r):
return [pos for pos in range(len(s)) if s.startswith(r,pos)]
你能给我解释一下enumerate(haystack):'行中“for i”中的“uu”吗?不太清楚这是怎么回事。@jacobmamoliti:这意味着你忽略了存在的变量enumerate()
允许您迭代字符串的位置和字符,但我们不使用字符。因此,我们只对字符串中的每个位置进行迭代。您还可以在enumerate(haystack)中为i,c编写:
以迭代字符串的每个位置i
和每个字符c
(同时)。请注意,“\ux”只是一种惯例,用于向人类读者明确说明-它的作用与使用“x”时没有任何不同我喜欢使用re
,但由于目标是“返回它在第一个字符串中出现的所有位置”,我认为这没有找到一些有趣的情况,其中r
在s
中多次出现,但其实例重叠。考虑下面的情况:<代码>多个查找(“BOBOB”,“BOB”)< /代码>。使用您的实现,字符串“bob”
肯定出现在“bobob”
中的位置2
,但它不会返回。我喜欢这一行,但我想我会把它作为一个可能的问题。“这对@Jacob可能没什么关系。”DarrenStone说得很好,他补充了另一个解决方案,同样适用于重叠匹配。
def multifind(string, value, start = 0, stop = None):
values = []
while True:
found = string.find(value, start, stop)
if found == -1:
break
values.append(found)
start = found + 1
return values
print multifind('hello abc abc', 'abc')
[6, 10]
def multi_find(s, r, start=0):
if start >= len(s):
return []
if s.startswith(r, start):
return [start] + multi_find(s, r, start+1)
else:
return multi_find(s, r, start+1)
def multi_find(s, r):
return [pos for pos in range(len(s)) if s.startswith(r,pos)]