我正在尝试查看字符串是否存在于另一个字符串中而不使用Python的预定义函数,例如find和index ..
现在我的函数将2个字符串作为参数,一个是我们要搜索的字符串,而另一个字符串是我们在第一个字符串中查找的字符串。
如果第一个字符串存在于第一个字符串中,我希望我的函数返回它在第一个字符串中出现的所有位置。
现在,我的函数能够找到第一个匹配项并返回索引,但我希望找到多个匹配项而不是第一个匹配项。
以下是我的代码:
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")
现在,这将只输出“0”,因为那是abc首先发生的地方..我怎样才能让它返回“0”和“6”(第二次出现的开始),基本上在发现之后继续检查之一。
我在考虑创建一个列表,列出它发生的所有地方,然后将我追加到那个列表,但是当我尝试这个时,没有任何东西对我有效。
答案 0 :(得分:7)
你可以这样做:
>>> 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
答案 1 :(得分:2)
使用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]
上述解决方案不适用于重叠的子字符串,例如'aa'
中有 3 'aaaa'
。所以,如果你想找到重叠的匹配,那么:
>>> haystack = "bobob"
>>> needle = "bob"
>>> [m.start() for m in re.finditer(r'(?={})'.format(re.escape(needle)), haystack)]
[0, 2]
答案 2 :(得分:1)
def multi_find(s, r):
s_len = len(s)
r_len = len(r)
_complete = []
if s_len < r_len:
n = -1
else:
for i in xrange(s_len):
# search for r in s until not enough characters are left
if s[i:i + r_len] == r:
_complete.append(i)
else:
i = i + 1
print(_complete)
multi_find("abcdefabc. asdli! ndsf abc saa abe?", "abc")
答案 3 :(得分:1)
def multi_find (s, r):
s_len = len(s)
r_len = len(r)
n = [] # assume r is not yet found in s
if s_len >= r_len:
m = s_len - r_len
i = 0
while i < m:
# search for r in s until not enough characters are left
if s[i:i + r_len] == r:
n.append(i)
i = i + 1
print (n)
multi_find("abcdefabc. asdli! ndsf acba saa abe?", "abc")
几乎只需用列表替换n,这样您就可以在找到它时不断添加值。即使找到匹配,你也需要递增i,它将永远停留在一个循环中,除非你有一个while n == -1约束,一旦匹配被发现它就会停止。
答案 4 :(得分:1)
执行此操作的最佳方法可能是继续调用find函数(这也是最快的)
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]
答案 5 :(得分:0)
注意:我认为这里的答案仍然是一个很好的“教学答案”,我在这个帖子的其他地方提交了一个更好的解决方案,没有递归。
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)
这允许您传递可选的start
位置,以便在s
开始搜索。
这个解决方案是递归的,可能是也可能不是最快的实现,但它是正确的,我相信它使代码很容易识别s
的每个位置的三种可能性中的每一种:
s
r
r
答案 6 :(得分:0)
@Jacob,我希望你会发现这个很短,但仍然很容易理解。
def multi_find(s, r):
return [pos for pos in range(len(s)) if s.startswith(r,pos)]