Как найти все вхождения подстроки?
В Python есть string.find()
и string.rfind()
для получения индекса подстроки в строке.
Мне интересно, есть ли что-то вроде string.find_all()
которое может вернуть все найденные индексы (не только первый с начала или первый с конца).
Например:
string = "test test test test"
print string.find('test') # 0
print string.rfind('test') # 15
#this is the goal
print string.find_all('test') # [0,5,10,15]
Ответы
Ответ 1
Нет простой встроенной строковой функции, которая делает то, что вы ищете, но вы можете использовать более мощные регулярные выражения:
import re
[m.start() for m in re.finditer('test', 'test test test test')]
#[0, 5, 10, 15]
Если вы хотите найти совпадающие совпадения, lookahead сделает это:
[m.start() for m in re.finditer('(?=tt)', 'ttt')]
#[0, 1]
Если вы хотите получить обратное вскрытие без перекрытий, вы можете комбинировать положительные и отрицательные образы в виде следующего вида:
search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]
re.finditer
возвращает генератор, поэтому вы можете изменить []
в приведенном выше re.finditer
на ()
чтобы получить генератор вместо списка, который будет более эффективен, если вы будете только повторять результаты один раз.
Ответ 2
>>> help(str.find)
Help on method_descriptor:
find(...)
S.find(sub [,start [,end]]) -> int
Таким образом, мы можем сами его построить:
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += len(sub) # use start += 1 to find overlapping matches
list(find_all('spam spam spam spam', 'spam')) # [0, 5, 10, 15]
Никаких временных строк или регулярных выражений не требуется.
Ответ 3
Здесь (очень неэффективный) способ получить все (т.е. даже совпадение):
>>> string = "test test test test"
>>> [i for i in range(len(string)) if string.startswith('test', i)]
[0, 5, 10, 15]
Ответ 4
Вы можете использовать re.finditer()
для совпадающих совпадений.
>>> import re
>>> aString = 'this is a string where the substring "is" is repeated several times'
>>> print [(a.start(), a.end()) for a in list(re.finditer('is', aString))]
[(2, 4), (5, 7), (38, 40), (42, 44)]
но не будет работать:
In [1]: aString="ababa"
In [2]: print [(a.start(), a.end()) for a in list(re.finditer('aba', aString))]
Output: [(0, 3)]
Ответ 5
Опять старый поток, но здесь мое решение использует генератор и обычный str.find
.
def findall(p, s):
'''Yields all the positions of
the pattern p in the string s.'''
i = s.find(p)
while i != -1:
yield i
i = s.find(p, i+1)
Пример
x = 'banananassantana'
[(i, x[i:i+2]) for i in findall('na', x)]
возвращает
[(2, 'na'), (4, 'na'), (6, 'na'), (14, 'na')]
Ответ 6
Приходите, давайте возместим вместе.
def locations_of_substring(string, substring):
"""Return a list of locations of a substring."""
substring_length = len(substring)
def recurse(locations_found, start):
location = string.find(substring, start)
if location != -1:
return recurse(locations_found + [location], location+substring_length)
else:
return locations_found
return recurse([], 0)
print(locations_of_substring('this is a test for finding this and this', 'this'))
# prints [0, 27, 36]
Нет необходимости в регулярных выражениях таким образом.
Ответ 7
Если вы ищете только один символ, это будет работать:
string = "dooobiedoobiedoobie"
match = 'o'
reduce(lambda count, char: count + 1 if char == match else count, string, 0)
# produces 7
Кроме того,
string = "test test test test"
match = "test"
len(string.split(match)) - 1
# produces 4
Моя догадка заключается в том, что ни один из них (особенно # 2) не ужасен.
Ответ 8
Это старый поток, но я заинтересовался и хотел поделиться своим решением.
def find_all(a_string, sub):
result = []
k = 0
while k < len(a_string):
k = a_string.find(sub, k)
if k == -1:
return result
else:
result.append(k)
k += 1 #change to k += len(sub) to not search overlapping results
return result
Он должен вернуть список позиций, в которых была найдена подстрока.
Прокомментируйте, если вы видите ошибку или комнату для улучшения.
Ответ 9
Этот поток немного стар, но это сработало для меня:
numberString = "onetwothreefourfivesixseveneightninefiveten"
testString = "five"
marker = 0
while marker < len(numberString):
try:
print(numberString.index("five",marker))
marker = numberString.index("five", marker) + 1
except ValueError:
print("String not found")
marker = len(numberString)
Ответ 10
Вы можете попробовать:
>>> string = "test test test test"
>>> for index,value in enumerate(string):
if string[index:index+(len("test"))] == "test":
print index
0
5
10
15
Ответ 11
Это делает трюк для меня, используя re.finditer
import re
text = 'This is sample text to test if this pythonic '\
'program can serve as an indexing platform for '\
'finding words in a paragraph. It can give '\
'values as to where the word is located with the '\
'different examples as stated'
# find all occurances of the word 'as' in the above text
find_the_word = re.finditer('as', text)
for match in find_the_word:
print('start {}, end {}, search string \'{}\''.
format(match.start(), match.end(), match.group()))
Ответ 12
Независимо от решений, предоставляемых другими, полностью зависит от доступного метода find() или любых доступных методов.
Каков основной базовый алгоритм для поиска всех вхождений подстрока в строке?
def find_all (строка, подстрока): "" Функция: Возврат всего индекса подстроки в строку Аргументы: Строка и строка поиска Возврат: возврат списка "" length = len (подстрока) с = 0 indexes = [] в то время как c < Len (строка): if string [c: c + length] == substring: indexes.append(с) с = с + 1 индексы возврата
Код>
Вы также можете наследовать класс str новому классу и можете использовать эту функцию ниже.
class newstr (str):
def find_all (строка, подстрока): "" Функция: Возврат всего индекса подстроки в строку Аргументы: Строка и строка поиска Возврат: возврат списка "" length = len (подстрока) с = 0 indexes = [] в то время как c < Len (строка): if string [c: c + length] == substring: indexes.append(с) с = с + 1 индексы возврата
Код>
Вызов метода
newstr.find_all ( "Вы находите этот ответ полезным?" это!", 'this')
Ответ 13
При поиске большого количества ключевых слов в документе используйте flashtext
from flashtext import KeywordProcessor
words = ['test', 'exam', 'quiz']
txt = 'this is a test'
kwp = KeywordProcessor()
kwp.add_keywords_from_list(words)
result = kwp.extract_keywords(txt, span_info=True)
Flashtext работает быстрее, чем регулярное выражение в большом списке поисковых слов.
Ответ 14
Вы можете легко использовать:
string.count('test')!
https://www.programiz.com/python-programming/methods/string/count
Ура!
Ответ 15
Разрезая, мы находим все возможные комбинации и добавляем их в список и определяем, сколько раз это происходит, используя функцию count
s=input()
n=len(s)
l=[]
f=input()
print(s[0])
for i in range(0,n):
for j in range(1,n+1):
l.append(s[i:j])
if f in l:
print(l.count(f))
Ответ 16
Питонический путь:
mystring = 'Hello World, this should work!'
find_all = lambda c,s: [x for x in range(c.find(s), len(c)) if c[x] == s]
# s represents the search string
# c represents the character string
find_all(mystring,'o') # will return all positions of 'o'
[4, 7, 20, 26]
>>>
Ответ 17
посмотрите ниже код
#!/usr/bin/env python
# coding:utf-8
'''黄哥Python'''
def get_substring_indices(text, s):
result = [i for i in range(len(text)) if text.startswith(s, i)]
return result
if __name__ == '__main__':
text = "How much wood would a wood chuck chuck if a wood chuck could chuck wood?"
s = 'wood'
print get_substring_indices(text, s)