python: поиск подстроки в строке

#python

#python

Вопрос:

Я пытаюсь написать программу, которая подсчитывает, сколько раз подстрока появляется в строке.

 word = "wejmfoiwstreetstreetskkjoih"
streets = "streets"
count = 0

if streets in word:
    count  = 1

print(count)
 

как вы можете видеть, «улицы» появляются дважды, но последние s улиц также являются началом улиц. Я не могу придумать способ зациклить это.

Спасибо!

Комментарии:

1. Может быть, начать здесь, docs.python.org/2.7/tutorial/index.html

2. Чтобы вы знали, правильная функция substr обычно ищет только одно вхождение подстроки и обычно возвращает индекс ее позиции в строке. В вашем примере вы также ищете только одно вхождение, если улицы в word well увеличивают количество только один раз, независимо от того, сколько раз подстрока ‘streets’ отображается в вашей строке. Здесь уже есть несколько хороших ответов, я просто хотел дать некоторое представление о том, почему ваша функция не работает.

Ответ №1:

Может быть выполнено с помощью регулярного выражения

 >>> import re
>>> text = 'streetstreets'
>>> len(re.findall('(?=streets)', text))
2
 

Из документации:

(?=…)

Соответствует, если … соответствует следующему, но не использует ни одной строки. Это называется предварительным утверждением. Например, Isaac (?=Asimov) будет соответствовать ‘Isaac’, только если за ним следует ‘Asimov’ .

Комментарии:

1. Это работает, но этот ответ был бы лучше, если бы регулярное выражение было несколько объяснено. В частности, что делает ?= do, поскольку он не работает с этим опущенным.

2. @EricWilson согласился, добавил часть из документов, где это объясняется

Ответ №2:

Быстро и грязно:

 >>> word = "wejmfoiwstreetstreetskkjoih"
>>> streets = "streets"
>>> sum(word[start:].startswith(streets) for start in range(len(word)))
2
 

Комментарии:

1. Мне нравится, как вы это делаете, 1!

Ответ №3:

Общим (хотя и не таким элегантным) способом был бы цикл, подобный этому:

 def count_substrings(stack, needle):
    idx = 0
    count = 0
    while True:
        idx = stack.find(needle, idx)   1 # next time look after this idx
        if idx <= 0:
            break
        count  = 1
    return count
 

Мои измерения показывают, что это в ~ 8,5 раз быстрее, чем решение с startswith для каждой подстроки.