Найти подстроку в строке, но только если целые слова? - PullRequest
16 голосов
/ 11 ноября 2010

Каков элегантный способ поиска строки в другой строке в Python, но только если подстрока находится внутри целых слов, а не является частью слова?

Возможно, пример продемонстрирует, что я имею в виду:

string1 = "ADDLESHAW GODDARD"
string2 = "ADDLESHAW GODDARD LLP"
assert string_found(string1, string2)  # this is True
string1 = "ADVANCE"
string2 = "ADVANCED BUSINESS EQUIPMENT LTD"
assert not string_found(string1, string2)  # this should be False

Как мне лучше всего написать функцию с именем string_found, которая будет делать то, что мне нужно?Я подумал, что, возможно, я мог бы выдумать что-то вроде этого:

def string_found(string1, string2):
   if string2.find(string1 + " "):
      return True
   return False

Но это не очень элегантно, и также не будет соответствовать string1, если он был в конце string2.Может быть, мне нужно регулярное выражение? (страх регулярного выражения)

Ответы [ 4 ]

27 голосов
/ 11 ноября 2010

Вы можете использовать регулярные выражения и специальный символ границы слова \b (выделите мной):

Соответствует пустой строке, но только в начале или в концеслова.Слово определяется как последовательность буквенно-цифровых символов или символов подчеркивания, поэтому конец слова обозначается пробелом или не алфавитно-цифровым символом без подчеркивания .Обратите внимание, что \b определяется как граница между \w и \W, поэтому точный набор символов, считающийся буквенно-цифровым, зависит от значений флагов UNICODE и LOCALE.Внутри символьного диапазона \b представляет символ возврата для совместимости со строковыми литералами Python.

def string_found(string1, string2):
   if re.search(r"\b" + re.escape(string1) + r"\b", string2):
      return True
   return False

Демо


Если границы слов для вас являются только пробелами, вы также можете использовать пробелы с пре- и добавлением пробелов в строках:

def string_found(string1, string2):
   string1 = " " + string1.strip() + " "
   string2 = " " + string2.strip() + " "
   return string2.find(string1)
8 голосов
/ 11 ноября 2010

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

import string

def find_substring(needle, haystack):
    index = haystack.find(needle)
    if index == -1:
        return False
    if index != 0 and haystack[index-1] not in string.whitespace:
        return False
    L = index + len(needle)
    if L < len(haystack) and haystack[L] not in string.whitespace:
        return False
    return True

А вот некоторый демонстрационный код (Кодовая панель - отличная идея: спасибо Феликсу Клингу за напоминание)

2 голосов
/ 09 января 2019

Я полагаю, что самый простой и самый питонический способ - разбить строки на отдельные слова и отсканировать совпадения:


    string = "My Name Is Josh"
    substring = "Name"

    for word in string.split():
        if substring == word:
            print("Match Found")

Для получения бонуса вот один пользователь:

any([substring == word for word in string.split()])
0 голосов
/ 30 декабря 2016

Один подход, использующий модуль re или регулярное выражение, который должен выполнить эту задачу:

import re

string1 = "pizza pony"
string2 = "who knows what a pizza pony is?"

search_result = re.search(r'\b' + string1 + '\W', string2)

print(search_result.group())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...