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)
- Структура
()|()
— выполняется условие либо в первой скобке, либо во второй. *.
— Любое количество любых символов, в том числе и пробельных.
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? Имеет ли значение заглавная буква? Как часто эта подстрока встречается в тексте? И каково расположение этих подстрок? Если вам нужен ответ на любой из этих вопросов, продолжайте читать.
Удалить рекламу
Обобщить проверку, удалив чувствительность к регистру
Строки Python чувствительны к регистру. Если подстрока, которую вы предоставляете, использует заглавные буквы, отличные от того же слова в вашем тексте, то Python не найдет ее. Например, если вы проверяете строчное слово "secret"
в заглавной версии исходного текста, проверка оператора принадлежности возвращает False
:
>>>
>>> title_cased_file_content = """Привет и добро пожаловать. ... Это специальный скрытый файл с секретным секретом. ... Я не хочу рассказывать вам секрет, ... Но я хочу по секрету сказать вам, что он у меня есть. >>> "секрет" в title_cased_file_content ЛОЖЬ
Несмотря на то, что слово секрет появляется несколько раз в тексте заголовка title_cased_file_content
, никогда не появляется во всех строчных буквах. Вот почему проверка, которую вы выполняете с помощью оператора членства, возвращает False
. Python не может найти строчную строку «секрет»
в предоставленном тексте.
У людей другой подход к языку, чем у компьютеров. Вот почему вы часто хотите игнорировать заглавные буквы, когда проверяете, содержит ли строка подстроку в Python.
Вы можете обобщить проверку подстроки, преобразовав весь входной текст в нижний регистр:
>>>
>>> file_content = title_cased_file_content.lower() >>> печать (файл_содержимое) привет и добро пожаловать. это специальный скрытый файл с секретным секретом. я не хочу раскрывать тебе тайну, но я хочу по секрету сказать вам, что у меня есть один. >>> "секрет" в файле_содержимого Истинный
Преобразование вводимого текста в нижний регистр — распространенный способ объяснить тот факт, что люди думают о словах, различающихся только заглавными буквами, как об одном и том же слове, а компьютеры — нет.
Примечание: В следующих примерах вы продолжите работать с file_content
, версией текста в нижнем регистре.
Если вы работаете с исходной строкой ( raw_file_content
) или с заголовком ( title_cased_file_content
), вы получите разные результаты, потому что они не в нижнем регистре. Не стесняйтесь попробовать это, пока вы работаете с примерами!
Теперь, когда вы преобразовали строку в нижний регистр, чтобы избежать непреднамеренных проблем, связанных с чувствительностью к регистру, пришло время углубиться и узнать больше о подстроке.
Узнайте больше о подстроке
Оператор принадлежности к
— отличный способ описательно проверить, есть ли в строке подстрока, но он не дает вам никакой дополнительной информации. Он идеально подходит для условных проверок, но что, если вам нужно больше узнать о подстроках?
Python предоставляет множество дополнительных строковых методов, которые позволяют вам проверять, сколько целевых подстрок содержит строка, искать подстроки в соответствии со сложными условиями или находить индекс подстроки в вашем тексте.
В этом разделе вы познакомитесь с некоторыми дополнительными строковыми методами, которые помогут вам больше узнать о подстроке.
Примечание: Возможно, вы видели следующие методы, используемые для проверки наличия в строке подстроки. Это возможно, но они не предназначены для этого!
Программирование — это творческая деятельность, и всегда можно найти разные способы выполнения одной и той же задачи. Однако для удобочитаемости вашего кода лучше всего использовать методы в том виде, в котором они предназначены для языка, с которым вы работаете.
Используя в
, вы подтверждаете, что строка содержит подстроку. Но вы не получили никакой информации о , где находится подстрока.
Если вам нужно знать, где в вашей строке встречается подстрока, вы можете использовать .index()
для строкового объекта:
>>>
>>> file_content = """привет и добро пожаловать. ... это специальный скрытый файл с секретным секретом. ... я не хочу раскрывать тебе секрет, ... но я хочу по секрету сказать вам, что он у меня есть.""" >>> file_content.index("секрет") 59
Когда вы вызываете .index()
для строки и передаете ей подстроку в качестве аргумента, вы получаете позицию индекса первого символа первого вхождения подстроки.
Примечание: Если Python не может найти подстроку, то . index()
вызывает исключение ValueError
.
Но что, если вы хотите найти другие вхождения подстроки? Метод .index()
также принимает второй аргумент, который может определить, с какой позиции индекса начинать поиск. Таким образом, передавая определенные позиции индекса, вы можете пропустить вхождения подстроки, которую вы уже идентифицировали:
>>>
>>> file_content.index("секрет", 60) 66
Когда вы передаете начальный индекс, который находится за первым вхождением подстроки, поиск Python начинается оттуда. В этом случае вы получите другое совпадение, а не ValueError
.
Это означает, что текст содержит подстроку более одного раза. Но как часто он там?
Вы можете использовать .count()
, чтобы быстро получить ответ, используя описательный и идиоматический код Python:
>>>
>>> file_content.count("секрет") 4
Вы использовали . count()
в строчной строке и передали подстроку "secret"
в качестве аргумента. Python подсчитал, как часто подстрока появляется в строке, и вернул ответ. Текст содержит подстроку четыре раза. Но как выглядят эти подстроки?
Вы можете проверить все подстроки, разделив текст по границам слов по умолчанию и распечатав слова на своем терминале, используя для цикла
:
>>>
>>> для слова в file_content.split(): ... если "секретно" в слове: ... печать (слово) ... секрет секрет. секрет, тайно
В этом примере вы используете .split()
для разделения текста в пробелах на строки, которые Python упаковывает в список. Затем вы перебираете этот список и используете в
для каждой из этих строк, чтобы увидеть, содержит ли она подстроку "secret"
.
Примечание: Вместо того, чтобы печатать подстроки, вы также можете сохранить их в новом списке, например, используя понимание списка с условным выражением:
>>>
>>> [дословно в file_content. split () если "секрет" в слове] ['секретно', 'секретно.', 'секретно', 'тайно']
В этом случае вы строите список только из слов, содержащих подстроку, что существенно фильтрует текст.
Теперь, когда вы можете проверить все подстроки, которые идентифицирует Python, вы можете заметить, что Python не заботится о том, есть ли какие-либо символы после подстроки 9.0008 «секрет» или нет. Он находит слово независимо от того, следует ли за ним пробел или знак препинания. Он даже находит такие слова, как "тайно"
.
Это приятно знать, но что делать, если вы хотите установить более строгие условия для проверки подстроки?
Удалить рекламу
Найти подстроку с условиями с помощью регулярного выражения
Вы можете сопоставлять только вхождения вашей подстроки, за которыми следует знак препинания, или идентифицировать слова, которые содержат подстроку плюс другие буквы, например "тайно"
.
В таких случаях, когда требуется более сложное сопоставление строк, вы можете использовать регулярные выражения или регулярные выражения с модулем Python re
.
Например, если вы хотите найти все слова, начинающиеся с «секрет»
, но за которыми следует хотя бы одна дополнительная буква, вы можете использовать символ слова регулярного выражения ( \w
), за которым следует квантификатор «плюс». ( +
):
>>>
>>> импорт >>> file_content = """привет и добро пожаловать. ... это специальный скрытый файл с секретным секретом. ... я не хочу раскрывать тебе секрет, ... но я хочу по секрету сказать вам, что он у меня есть.""" >>> re.search(r"secret\w+", file_content)
Функция re.search()
возвращает как подстроку, соответствующую условию, так и ее начальную и конечную позиции индекса, а не просто True
!
Затем вы можете получить доступ к этим атрибутам с помощью методов объекта Match
, который обозначается как m
:
>>>
>>> m = re. search(r"secret\w+", file_content) >>> м.группа() 'тайно' >>> м.промежуток() (128, 136)
Эти результаты обеспечивают большую гибкость для продолжения работы с совпавшей подстрокой.
Например, вы можете искать только те подстроки, за которыми следует запятая (,
) или точка (.
):
>>>
>>> re.search(r"секрет[\.,]", file_content)
В вашем тексте есть два возможных совпадения, но вы сопоставили только первый результат, соответствующий вашему запросу. Когда вы используете re.search()
, Python снова находит только первых совпадений. Что делать, если вы хотите все упоминания "секретных"
, которые соответствуют определенному условию?
Чтобы найти все совпадения, используя re
, вы можете работать с re.findall()
:
>>>
>>> re. findall(r"секрет[\.,]", file_content) ['секрет.', 'секрет']
Используя re.findall()
, вы можете найти все совпадения шаблона в вашем тексте. Python сохраняет для вас все совпадения в виде строк в списке.
Когда вы используете группу захвата, вы можете указать, какую часть совпадения вы хотите оставить в своем списке, заключив эту часть в круглые скобки:
>>>
>>> re.findall(r"(секрет)[\.,]", file_content) ['секрет', 'секрет']
Заключив секрет в круглые скобки, вы определили единую группу захвата. Функция findall()
возвращает список строк, соответствующих этой захватываемой группе, если в шаблоне имеется ровно одна захватываемая группа. Добавив скобки вокруг secret , вам удалось избавиться от пунктуации!
Примечание: Помните, что в вашем тексте было четыре вхождения подстроки "secret"
, и, используя re
, вы отфильтровали два конкретных вхождения, которые вы сопоставили в соответствии с особыми условиями.
Использование re.findall()
с группами соответствия — это мощный способ извлечения подстрок из вашего текста. Но вы получаете только список из строк , что означает, что вы потеряли позиции индекса, к которым у вас был доступ, когда вы использовали re.search()
.
Если вы хотите сохранить эту информацию, то re
может дать вам все совпадения в итераторе:
>>>
>>> для совпадения в re.finditer(r"(secret)[\.,]", file_content): ... печать (совпадение) ...
Когда вы используете re.finditer()
и передаете ему шаблон поиска и ваш текстовый контент в качестве аргументов, вы можете получить доступ к каждому Совпадение с объектом
, который содержит подстроку, а также ее начальную и конечную позиции индекса.
Вы можете заметить, что в этих результатах появляются знаки препинания, даже если вы все еще используете группу захвата. Это связано с тем, что строковое представление объекта Match
отображает все совпадение, а не только первую группу захвата.
Но объект Match
является мощным контейнером информации, и, как вы уже видели ранее, вы можете выбрать именно ту информацию, которая вам нужна:
>>>
>>> для совпадения в re.finditer(r"(secret)[\.,]", file_content): ... печать (соответствие.группа (1)) ... секрет секрет
Вызвав .group()
и указав, что вам нужна первая группа захвата, вы выбрали слово secret без знаков препинания из каждой совпадающей подстроки.
При использовании регулярных выражений вы можете более подробно изучить сопоставление подстрок. Вместо того, чтобы просто проверять, содержит ли строка другую строку, вы можете искать подстроки в соответствии со сложными условиями.
Примечание: Если вы хотите больше узнать об использовании групп захвата и составлении более сложных шаблонов регулярных выражений, вы можете глубже изучить регулярные выражения в Python.
Использование регулярных выражений с относительно
— хороший подход, если вам нужна информация о подстроках или если вам нужно продолжить работу с ними после того, как вы нашли их в тексте. Но что, если вы работаете с табличными данными? Для этого вы обратитесь к пандам.
Удалить рекламу
Найти подстроку в столбце pandas DataFrame
Если вы работаете с данными, которые поступают не из простого текстового файла или пользовательского ввода, а из файла CSV или листа Excel, вы можете использовать тот же подход, который обсуждался выше.
Однако есть лучший способ определить, какие ячейки в столбце содержат подстроку: вы будете использовать pandas ! В этом примере вы будете работать с CSV-файлом, содержащим поддельные названия компаний и слоганы. Вы можете скачать файл ниже, если хотите работать вместе:
Когда вы работаете с табличными данными в Python, обычно лучше сначала загрузить их в pandas DataFrame
:
>>>
>>> импортировать панд как pd >>> компании = pd. read_csv("companies.csv") >>> компании.форма (1000, 2) >>> компании.голова() слоган компании 0 Кувалис-Нолан произвели революцию в метриках следующего поколения 1. Дитрих-Шамплин предлагает передовые функциональные возможности 2 ориентированных на пользователя информационных посредника West Inc. 3 ООО «Венер» использует липких информационных посредников 4 Langworth Inc заново изобретает магнитные сети
В этом блоке кода вы загрузили файл CSV, содержащий тысячу строк поддельных данных компании, в кадр данных pandas и проверили первые пять строк, используя .head()
.
После того, как вы загрузили данные в DataFrame, вы можете быстро запросить весь столбец pandas, чтобы отфильтровать записи, содержащие подстроку:
>>>
>>> компании[companies.slogan.str.contains("секрет")] слоган компании 7 Maggio LLC нацелена на секретные ниши 117 фирменных секретных методологий Kub and Sons 654 Секретные парадигмы синдиката Косс-Зулауф 656 Бернье-Кин тайно синтезирует внутреннюю полосу пропускания 921 Ward-Shield использует секретную электронную коммерцию 945 Williamson Group выпускает секретные экшн-предметы
Вы можете использовать . str.contains()
в столбце pandas и передать ему подстроку в качестве аргумента для фильтрации строк, содержащих подстроку.
Примечание: Оператор индексирования ( []
) и оператор атрибута ( .
) предлагают интуитивно понятные способы получения отдельного столбца или фрагмента DataFrame.
Однако, если вы работаете с производственным кодом, который связан с производительностью, панды рекомендуют использовать оптимизированные методы доступа к данным для индексации и выбора данных.
Когда вы работаете с .str.contains()
и вам нужны более сложные сценарии сопоставления, вы также можете использовать регулярные выражения! Вам просто нужно передать шаблон поиска, совместимый с регулярным выражением, в качестве аргумента подстроки:
>>>
>>> компании[companies.slogan.str.contains(r"secret\w+")] слоган компании 656 Бернье-Кин тайно синтезирует внутреннюю полосу пропускания
В этом фрагменте кода вы использовали тот же шаблон, что и ранее, для сопоставления только слов, содержащих секрет , но затем продолжите с одним или несколькими символами слова ( \w+
). Кажется, только одна из компаний в этом поддельном наборе данных тайно управляет !
Вы можете написать любой сложный шаблон регулярного выражения и передать его .str.contains()
, чтобы вырезать из столбца pandas только те строки, которые вам нужны для анализа.
Заключение
Как настойчивый кладоискатель, вы нашли каждый «секрет»
, как бы хорошо он ни был спрятан! В процессе вы узнали, что лучший способ проверить, содержит ли строка подстроку в Python, — это использовать в операторе членства
.
Вы также узнали, как описательно использовать два других строковых метода , которые часто неправильно используются для проверки подстрок:
-
.count()
для подсчета вхождений подстроки в строку -
.index()
, чтобы получить позицию индекса начала подстроки
После этого вы узнали, как находить подстроки в соответствии с более сложными условиями с помощью регулярные выражения и несколько функций в модуле Python re
.
Наконец, вы также узнали, как можно использовать метод DataFrame .str.contains()
для проверки того, какие записи в pandas DataFrame содержат подстроку.
Теперь вы знаете, как выбрать наиболее идиоматический подход при работе с подстроками в Python. Продолжайте использовать наиболее описательный метод для работы, и вы напишете код, который приятно читать и быстро понимать другим.
python – Как найти все вхождения подстроки?
Задавать вопрос
спросил
Изменено 2 месяца назад
Просмотрено 724k раз
Python имеет string.find()
и string.rfind()
для получения индекса подстроки в строке.
Мне интересно, есть ли что-то вроде string.find_all()
, которое может вернуть все найденные индексы (не только первый с начала или первый с конца).
Например:
строка = "тест тест тест тест" напечатать string.find('тест') # 0 print string.rfind('тест') # 15 #это цель print string.find_all('test') # [0,5,10,15]
Для подсчет вхождений, см. Подсчет количества вхождений подстроки в строке.
- питон
- строка
2
Не существует простой встроенной строковой функции, которая делает то, что вам нужно, но вы можете использовать более мощные регулярные выражения:
import re [m.start() для m в re.finditer('test', 'test test test test')] #[0, 5, 10, 15]
Если вы хотите найти перекрывающиеся совпадения, это сделает предварительный просмотр:
[m.start() для m в re.finditer('(?=tt)', 'ttt')] #[0, 1]
Если вам нужен обратный поиск без перекрытий, вы можете объединить положительный и отрицательный просмотр в следующее выражение:
search = 'tt' [m. start() для m в re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt ')] #[1]
re.finditer
возвращает генератор, поэтому вы можете изменить []
выше на ()
, чтобы получить генератор вместо списка, который будет более эффективным, если вы только перебираете результаты один раз.
9
>>> help(str.find) Справка по method_descriptor: находить(...) S.find(sub [start [end]]) -> int
Таким образом, мы можем построить его сами:
def find_all(a_str, sub): начало = 0 пока верно: start = a_str.find(sub, start) если start == -1: возврат начало выхода start += len(sub) # используйте start += 1 для поиска перекрывающихся совпадений list(find_all('спам спам спам спам', 'спам')) # [0, 5, 10, 15]
Временные строки или регулярные выражения не требуются.
6
Вот (очень неэффективный) способ получить все (т. е. даже перекрывающиеся) совпадений:
>>> string = "test test test test" >>> [i для i в диапазоне (len(string)) if string.startswith('test', i)] [0, 5, 10, 15]
3
Использовать re.finditer
:
импортировать повторно предложение = ввод ("Дайте мне предложение") word = input("Какое слово вы хотите найти") для совпадения в re.finditer(слово, предложение): печать (match.start(), match.end())
Для слово = "это"
и предложение = "это предложение это это"
это даст результат:
(0, 4) (19, 23) (24, 28)
2
Опять же, старая тема, но вот мое решение с использованием генератора и простого str.find
.
def findall(p, s): '''Выдает все позиции образец p в строке s.''' я = с. найти (р) пока я != -1: выход я я = s. find(p, i+1)
Пример
x = 'banananassantana' [(i, x[i:i+2]) для i в findall('na', x)]
возвращает
[(2, 'нет'), (4, 'нет'), (6, 'нет'), (14, 'нет')]
3
Вы можете использовать re.finditer()
для неперекрывающихся совпадений.
>>> импорт повторно >>> aString = 'это строка, в которой подстрока "is" повторяется несколько раз' >>> print [(a.start(), a.end()) для списка (re.finditer('is', aString))] [(2, 4), (5, 7), (38, 40), (42, 44)]
, но не будет работать для:
В [1]: aString="ababa" В [2]: напечатайте [(a.start(), a.end()) для списка в (re.finditer('aba', aString))] Вывод: [(0, 3)]
2
Давай рекурсируем вместе.
определение location_of_substring (строка, подстрока): """Вернуть список местоположений подстроки.""" substring_length = длина (подстрока) def recurse (locations_found, start): location = string. find (подстрока, начало) если местоположение != -1: вернуть рекурсию (местоположения_найдено + [местоположение], местоположение+подстрока_длина) еще: вернуть location_found вернуть рекурсию ([], 0) print(locations_of_substring('это тест на нахождение этого и этого', 'это')) # печатает [0, 27, 36]
Таким образом, регулярные выражения не нужны.
2
Если вы ищете только один символ, это будет работать:
string = "dooobiedoobiedoobie" совпадение = 'о' уменьшить (количество лямбда, char: количество + 1, если char == соответствует, иначе количество, строка, 0) # производит 7
Кроме того,
string = "тест тест тест тест" совпадение = "тест" len(string.split(match)) - 1 # производит 4
Я подозреваю, что ни один из них (особенно #2) не обладает ужасной производительностью.
1
это старая тема, но я заинтересовался и хотел поделиться своим решением.
по определению find_all (a_string, sub): результат = [] к = 0 пока k < len(a_string): k = a_string.find(sub, k) если к == -1: вернуть результат еще: результат .append(k) k += 1 # измените на k += len(sub), чтобы не искать перекрывающиеся результаты вернуть результат
Должен вернуть список позиций, в которых была найдена подстрока. Пожалуйста, прокомментируйте, если вы видите ошибку или место для улучшения.
Это помогает мне использовать re.finditer
import re text = 'Это образец текста для проверки, является ли этот pythonic'\ 'может служить платформой для индексации '\ 'нахождение слов в абзаце. Это может дать '\ 'значения относительно того, где находится слово с '\ «различные примеры, как указано» # найти все вхождения слова as в приведенном выше тексте find_the_word = re.finditer('как', текст) для совпадения в find_the_word: print('начало {}, конец {}, строка поиска \'{}\''. формат(match.start(), match.end(), match.group()))
Этот поток немного устарел, но у меня сработало:
numberString = "onetwothreefourfivesixseveneightninefiveten" тестовая строка = "пять" маркер = 0 в то время как маркер < len(numberString): пытаться: print(numberString.index("пять",маркер)) маркер = числовая строка.индекс ("пять", маркер) + 1 кроме ValueError: print("Строка не найдена") маркер = длина (строка числа)
Вы можете попробовать:
>>> строка = "тест тест тест тест" >>> для индекса, значение в перечислении (строка): если строка[индекс:индекс+(len("тест"))] == "тест": индекс печати 0 5 10 15
Вы можете попробовать:
импортировать повторно str1 = "Это платье выглядит хорошо, у тебя хороший вкус в одежде." substr = "хорошо" результат = [_.start() для _ в re.finditer(substr, str1)] # результат = [17, 32]
2
При поиске большого количества ключевых слов в документе используйте flashtext
из flashtext import KeywordProcessor слова = ['тест', 'экзамен', 'викторина'] txt = «это тест» kwp = процессор ключевых слов () kwp. add_keywords_from_list(слова) результат = kwp.extract_keywords (txt, span_info = True)
Flashtext работает быстрее, чем регулярное выражение в большом списке поисковых слов.
Эта функция не просматривает все позиции внутри строки, она не тратит вычислительные ресурсы. Моя попытка:
def findAll (строка, слово): all_positions=[] следующая_позиция=-1 пока верно: next_pos=string.find(слово,next_pos+1) если (следующая_позиция<0): перерыв all_positions.append(следующая_позиция) вернуть все_позиции
, чтобы использовать его, назовите его так:
result=findAll('это большое слово, чувак, сколько там слов?','слово')
0
src = input() # мы найдем подстроку в этой строке sub = input() # подстрока разрешение = [] pos = src.find(sub) а поз != -1: res.append(pos) pos = src.find(sub, pos + 1)
1
Какие бы решения не предоставлялись другими, они полностью основаны на доступном методе find() или любых других доступных методах.
Каков базовый алгоритм поиска всех вхождений подстрока в строке?
определение find_all (строка, подстрока): """ Функция: Возврат всего индекса подстроки в строке Аргументы: строка и строка поиска Возврат: Возврат списка """ длина = длина (подстрока) с=0 индексы = [] в то время как c < len (строка): если строка[c:c+length] == подстрока: indexes.append(c) с=с+1 индексы возврата
Вы также можете наследовать класс str новому классу и можете использовать эту функцию ниже.
класс ньюстр(ул): def find_all (строка, подстрока): """ Функция: Возврат всего индекса подстроки в строке Аргументы: строка и строка поиска Возврат: Возврат списка """ длина = длина (подстрока) с=0 индексы = [] в то время как c < len (строка): если строка[c:c+length] == подстрока: indexes.append(c) с=с+1 индексы возврата
Вызов метода
newstr. find_all('Считаете ли вы этот ответ полезным? Тогда проголосуйте за это!','это')
Это решение похожего вопроса от hackerrank. Я надеюсь, что это может помочь вам.
импорт а = ввод () б = ввод () если б не в а: напечатать((-1,-1)) еще: #создать два списка как start_indc = [m.start() для m в re.finditer('(?=' + b + ')', a)] для i в диапазоне (len (start_indc)): print((start_indc[i], start_indc[i]+len(b)-1))
Вывод:
ааадаа аа (0, 1) (1, 2) (4, 5)
Вот решение, которое я придумал, используя выражение присваивания (новая функция начиная с Python 3.8):
строка = "тест тест тест тест" фраза = "тест" начало = -1 результат = [(начало:= string.find(фраза, начало + 1)) для _ в диапазоне(string.count(фраза))]
Вывод:
[0, 5, 10, 15]
Я думаю, что наиболее чистым способом решения является без библиотек и выходов:
def find_all_occurrences(string, sub): index_of_occurrences = [] текущий_индекс = 0 пока верно: current_index = string. find(sub, current_index) если текущий_индекс == -1: вернуть index_of_occurrences еще: index_of_occurrences.append(current_index) текущий_индекс += длина (суб) find_all_occurrences (строка, подстрока)
Примечание: find()
метод возвращает -1
, когда он ничего не может найти
Пифонический способ будет таким:
mystring = 'Привет, мир, это должно работать!' find_all = lambda c,s: [x для x в диапазоне (c.find(s), len(c)) if c[x] == s] # s представляет строку поиска # c представляет строку символов find_all(mystring,'o') # вернет все позиции 'o' [4, 7, 20, 26] >>>
2
, если вы хотите использовать только numpy, вот решение
импортировать numpy как np S = "тест тест тест тест" S2 = «тест» inds = np.cumsum([len(k)+len(S2) для k в S.split(S2)[:-1]])- len(S2) печать (инд.)
, если вы хотите использовать без re(regex), то:
find_all = lambda _str,_w : [i for i in range(len(_str)) if _str. startswith(_w,i)] строка = "тест тест тест тест тест" print(find_all(string, 'test')) # >>> [0, 5, 10, 15]
смотрите ниже код
#!/usr/bin/env Python # кодировка: utf-8 '''黄哥Python''' def get_substring_indices (текст, с): результат = [i для i в диапазоне (длина (текст)) if text.startswith (s, i)] вернуть результат если __name__ == '__main__': text = "Сколько древесины мог бы зажать дровосек, если бы дровосек мог забивать дрова?" с = 'дерево' распечатать get_substring_indices (текст, с)
1
определение find_index (строка, пусть): enumerated = [место для места, буква в перечислении (строка), если буква == пусть] вернуть перечисленные
например:
find_index("привет, найди d", "d")
возвращает:
[4, 7, 13, 15]
1
Не совсем то, что спрашивал OP, но вы также можете использовать функцию разделения, чтобы получить список, где все подстроки не встречаются . OP не указал конечную цель кода, но если ваша цель в любом случае состоит в том, чтобы удалить подстроки, то это может быть простой однострочный код. Вероятно, есть более эффективные способы сделать это с большими строками; регулярные выражения были бы предпочтительнее в этом случае
# Извлечь все неподстроки s = "пример строки" s_no_dash = s.split('-') # >>> s_no_dash # ['an', 'пример', 'строка'] # Или извлеките и соедините их в предложение s_no_dash3 = ' '.join(s.split('-')) # >>> s_no_dash3 # 'пример строки'
Кратко просмотрел другие ответы, так что извините, если это уже там.
по определению count_substring(строка, подстрока): с=0 для я в диапазоне (0, len (строка)-2): если строка[i:i+len(sub_string)] == sub_string: с+=1 вернуться с если __name__ == '__main__': строка = ввод (). полоса () sub_string = ввод (). полоса () count = count_substring(строка, sub_string) распечатать (количество)
2
Я столкнулся с той же проблемой и сделал это:
hw = 'Hello oh World!' list_hw = список (hw) о_in_hw = [] пока верно: о = hw. find('o') если о != -1: o_in_hw.append(o) list_hw[o] = ' ' hw = ''.join(list_hw) еще: печать (o_in_hw) перерыв
Я довольно новичок в программировании, поэтому вы, вероятно, можете упростить его (и, если вы планируете использовать его постоянно, конечно, сделайте его функцией).
Все работает так, как я и делал.
Редактировать: пожалуйста, учтите, что это только для отдельных символов, и это изменит вашу переменную, поэтому вам нужно создать копию строки в новой переменной, чтобы сохранить ее, я не помещал ее в код, потому что это легко и просто только чтобы показать, как я заставил это работать.
Нарезая, мы находим все возможные комбинации, добавляем их в список и находим количество раз, когда они встречаются, используя count
function
s=input() n=длина(ы) л=[] е = ввод () печать (с [0]) для я в диапазоне (0, n): для j в диапазоне (1, n + 1): l.append(s[i:j]) если f в l: печать (л.