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

python — Поиск подстрок в строке

Есть ли в python встроенные инструкции, которые позволяют осуществлять поиск подстрок в строке?

Строка: Попробуй этих чудесных и спелых фруктов. Попробуешь?

Хочу найти: Поп

Должен получить: [0, 43]. Т.е. индексы всех вхождений в строку.

  • python
  • python-3.x
  • алгоритм

1

Можно использовать алгоритм Кнута-Морриса-Пратта

def find_all(source, sub):
    def prefix_func(s):
        pr = [0] * (len(s))
        for i in range(1, len(s)):
            k = pr[i - 1]
            while k > 0 and s[k] != s[i]:
                k = pr[k - 1]
            if s[k] == s[i]:
                k = k + 1
            pr[i] = k
        return pr
    result = prefix_func(sub + "$" + source)  # вместо доллара может быть любой другой не встречаюшийся символ
    return [index for index, element in enumerate(result) if (element >= len(sub))]

Работать будет за линейное время от суммарных длин строк. Если вы хотите искать часто по одной строке, то кажется надо будет написать алгоритм Ахо-Корасика.

5

Можно использовать регулярные выражения:

import re
print([m.start() for m in re.finditer('test', 'test test test test')])
#[0, 5, 10, 15]

4

Как на счет такого варианта:

def find_all(s, sub):
    res = []
    cur_pos = 0
    for x in s.split(sub)[:-1]:
        cur_pos += len(x)
        res.append(cur_pos)
        cur_pos += len(sub)
    return res

In [187]: find_all("Попробуй этих чудесных и спелых фруктов. Попробуешь?", "Поп")
Out[187]: [0, 41]

5

Вы можете собирать список вхождений строки, каждый раз обрезая уже учтённое вхождение

def findall(s, substr):
  def searching(s, substr):
    offset = 0
    while s. find(substr) != -1:
      yield s.find(substr) + offset
      offset += len(substr) + s.find(substr)
      s = s[s.find(substr) + len(substr):]
  return list(searching(s,substr))
print(findall('Попробуй этих чудесных и спелых фруктов. Попробуешь?', 'Поп'))

Важной частью этого метода является хранение «смещения» строки. Чтобы верно указывать индекс вхождения в изначальную строку, нужно помнить, сколько символов мы уже убрали.
Упростить эту конструкцию можно, убирая вхождения справа — тогда индексы не будут смещаться:

def findall(s, substr):
  def searching(s, substr):
    while s.rfind(substr) != -1:
      yield s.rfind(substr)
      s = s[:s.rfind(substr)]
  return list(reversed(list(searching(s,substr))))
print(findall('Попробуй этих чудесных и спелых фруктов. Попробуешь?', 'Поп'))

Результат работы обеих вариантов функций:

[0, 41] # да, второе вхождение подстроки находится именно на 41 позиции, а не на 43

1

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

python — Поиск подстроки в начале и конце строки с помощью регулярного выражения

Вопрос задан

Изменён 1 год 6 месяцев назад

Просмотрен 339 раз

Задача:

Имеется игра «Саймон говорит». \s*(Simon says)(тут должно что-то быть) (Simon says)\s*$» def what_to_do(instructions): if bool(re.fullmatch(phrase, instructions)): return(«I» + instructions) else: return(«I won’t do it!»)

  • python
  • python-3.x
  • re
  • bool

Вам не обязательно использовать регулярные выражения, чтобы выполнить эту задачу. Вы можете использовать методы строк .startswith() и .endswith():

def what_to_do(instructions):
  if instructions.startswith("Simon says"):
    return("I " + instructions[10:])
  elif instructions.endswith("Simon says"):
    return("I " + instructions[:-10])
  else:
      return("I won't do it!")
print(what_to_do("Simon says jump!"))
print(what_to_do("Please, jump!"))

Метод с использованием регулярных выражений:

import re
r = "(Simon says .*)|(.* Simon says)"
def what_to_do(instructions):
    if bool(re.fullmatch(r, instructions)):
        return("I " + re.sub("\s*Simon says\s*", "", instructions))
    else:
        return("I won't do it!")
print(what_to_do("Simon says jump!"))
print(what_to_do("Please, jump!"))

Объяснение регулярного выражения:

(Simon says . *)|(.* Simon says)

  1. Структура ()|() — выполняется условие либо в первой скобке, либо во второй.
  2. *. — Любое количество любых символов, в том числе и пробельных.

4

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Как проверить, содержит ли строка Python подстроку — настоящий Python Питон.

Идентификация таких подстрок пригодится, когда вы работаете с текстовым содержимым из файла или после того, как вы получили пользовательский ввод. Вы можете выполнять различные действия в своей программе в зависимости от того, присутствует подстрока или нет.

В этом руководстве вы сосредоточитесь на самом Pythonic способе решения этой задачи, используя оператор членства в . Кроме того, вы узнаете, как определить правильные строковые методы для связанных, но разных вариантов использования.

Наконец, вы также узнаете, как находить подстроки в столбцах pandas . Это полезно, если вам нужно выполнить поиск данных из CSV-файла. Вы могли бы использовать подход, который вы узнаете в следующем разделе, но если вы работаете с табличные данные , лучше всего загрузить данные в pandas DataFrame и искать подстроки в pandas.

Как убедиться, что строка Python содержит другую строку

Если вам нужно проверить, содержит ли строка подстроку, используйте оператор принадлежности Python в . В Python это рекомендуемый способ подтверждения наличия подстроки в строке:

.

>>>

 >>> raw_file_content = """Привет и добро пожаловать.
... Это специальный скрытый файл с СЕКРЕТНЫМ секретом.
... Я не хочу раскрывать тебе Секрет,
... но я хочу по секрету сказать вам, что он у меня есть."""
>>> "секрет" в raw_file_content
Истинный
 

Оператор членства в дает вам быстрый и удобный способ проверить, присутствует ли подстрока в строке. Вы можете заметить, что строка кода читается почти как английский язык.

Примечание: Если вы хотите проверить, является ли подстрока , а не в строке, вы можете использовать не в :

>>>

 >>> "secret" не в raw_file_content
ЛОЖЬ
 

Поскольку подстрока "секретная" присутствует в raw_file_content , оператор не в возвращает False .

При использовании в выражение возвращает логическое значение:

  • Истинно , если Python нашел подстроку
  • Ложь , если Python не нашел подстроку

Вы можете использовать этот интуитивно понятный синтаксис в условных операторах для принятия решений в вашем коде:

>>>

 >>> если "секрет" в raw_file_content:
... печать("Найдено!")
...
Найденный!
 

В этом фрагменте кода вы используете оператор принадлежности, чтобы проверить, является ли "secret" подстрокой raw_file_content . Если это так, то вы напечатаете сообщение на терминал. Любой код с отступом будет выполняться только в том случае, если проверяемая вами строка Python содержит предоставленную вами подстроку.

Примечание: Python всегда рассматривает пустые строки как подстроку любой другой строки, поэтому проверка на наличие пустой строки в строке возвращает

True :

>>>

 >>> "" в "секрет"
Истинный
 

Это может показаться удивительным, поскольку Python считает строки emtpy ложными, но это крайний случай, о котором полезно помнить.

Оператор членства в — ваш лучший друг, если вам просто нужно проверить, содержит ли строка Python подстроку.

Однако что, если вы хотите узнать больше о подстроке? Если вы прочитаете текст, хранящийся в raw_file_content , то вы заметите, что подстрока встречается более одного раза и даже в разных вариациях!

Какие из этих вхождений нашел Python? Имеет ли значение заглавная буква? Как часто эта подстрока встречается в тексте? И каково расположение этих подстрок? Если вам нужен ответ на любой из этих вопросов, продолжайте читать.