How to match a whole word with a regular expression?
Как сопоставить целое слово с регулярным выражением?
У меня возникли проблемы с поиском правильного регулярного выражения для приведенного ниже сценария:
Допустим:
a = "this is a sample"
Я хочу сопоставить целое слово - например, match "hi" должен возвращать False, поскольку "hi" это не слово, и "is" должен возвращать True, поскольку слева и справа нет альфа-символа.
\b Сопоставляет пустую строку, но только в начале или конце слова.
Обратите внимание, что re модуль использует наивное определение "word" как "последовательности буквенно-цифровых символов или подчеркивания", где "буквенно-цифровой" зависит от локали или параметров unicode.
Также обратите внимание, что без префикса необработанной строки \b рассматривается как "пробел" вместо границы слова регулярного выражения.
Ответ 2
Попробуйте использовать символьный класс "граница слова" в модуле регулярных выражений, re:
x="this is a sample" y="this isis a sample." regex=re.compile(r"\bis\b") # For ignore case: re.compile(r"\bis\b", re.IGNORECASE)
\b сопоставляет пустую строку, но только в начале или конце слова
...
Например, r'\bfoo\b' совпадает 'foo', 'foo.', '(foo)''bar foo baz' но не 'foobar' или 'foo3'
Ответ 3
Я думаю, что поведение, желаемое OP, не было полностью достигнуто с использованием приведенных ответов. В частности, не был достигнут желаемый вывод логического значения. Приведенные ответы действительно помогают проиллюстрировать концепцию, и я думаю, что они превосходны. Возможно, я могу проиллюстрировать, что я имею в виду, заявив, что я думаю, что OP использовал примеры, использованные из-за следующего.
Приведенная строка была,
a = "this is a sample"
Затем в OP говорилось,
Я хочу сопоставить целое слово - например, совпадение "hi" должно возвращать False поскольку "hi" это не слово ...
Насколько я понимаю, ссылка идет на маркер поиска, "hi" поскольку он находится в word, "this". Если кто-то будет искать в строке aслово"hi", он должен получить False ответ.
Операция продолжается,
... и "is" должен возвращать True, поскольку слева и справа нет альфа-символа.
В данном случае речь идет о маркере поиска, "is" поскольку он находится в слове "is". Я надеюсь, это поможет прояснить, почему мы используем границы слов. Другие ответы имеют такое поведение: "не возвращайте слово, если это слово не найдено само по себе, а не внутри других слов". "Word boundary" Класс сокращенных символов прекрасно справляется с этой работой.
До этого момента в примерах использовалось только слово "is". Я думаю, что эти ответы правильные, но я думаю, что есть больше фундаментального значения вопроса, которое необходимо рассмотреть. Для понимания концепции следует обратить внимание на поведение других строк поиска. Другими словами, нам нужно обобщить (отличный) ответ @georg, используя re.match(r"\bis\b", your_string) ту же r"\bis\b" концепцию, которая также используется в ответе @OmPrakash, который начал обобщающее обсуждение, показав
>>> y="this isis a sample." >>> regex=re.compile(r"\bis\b") # For ignore case: re.compile(r"\bis\b", re.IGNORECASE) >>> regex.findall(y) []
Допустим, метод, который должен демонстрировать поведение, которое я обсуждал, называется
find_only_whole_word(search_string, input_string)
Тогда следует ожидать следующего поведения.
>>> a = "this is a sample" >>> find_only_whole_word("hi", a) False >>> find_only_whole_word("is", a) True
Еще раз, вот как я понимаю вопрос OP. У нас есть шаг к такому поведению с ответом от @georg , но это немного сложно интерпретировать / реализовать. а именно
>>> import re >>> a = "this is a sample" >>> re.search(r"\bis\b", a) <_sre.SRE_Match object; span=(5, 7), match='is'> >>> re.search(r"\bhi\b", a) >>>
Вторая команда не выводит результат. Полезный ответ от @OmPrakesh показывает результат, но не True или False.
Вот более полная выборка ожидаемого поведения.
>>> find_only_whole_word("this", a) True >>> find_only_whole_word("is", a) True >>> find_only_whole_word("a", a) True >>> find_only_whole_word("sample", a) True # Use "ample", part of the word, "sample": (s)ample >>> find_only_whole_word("ample", a) False # (t)his >>> find_only_whole_word("his", a) False # (sa)mpl(e) >>> find_only_whole_word("mpl", a) False # Any random word >>> find_only_whole_word("applesauce", a) False >>>
Это может быть достигнуто с помощью следующего кода:
deffind_only_whole_word(search_string, input_string): # Create a raw string with word boundaries from the user's input_string raw_search_string = r"\b" + search_string + r"\b"
match_output = re.search(raw_search_string, input_string) ##As noted by @OmPrakesh, if you want to ignore case, uncomment ##the next two lines #match_output = re.search(raw_search_string, input_string, # flags=re.IGNORECASE)
Далее следует простая демонстрация. Запустите интерпретатор Python из того же каталога, в котором вы сохранили файл, find_only_whole_word.py.
>>> from find_only_whole_word import find_only_whole_word >>> a = "this is a sample" >>> find_only_whole_word("hi", a) False >>> find_only_whole_word("is", a) True >>> find_only_whole_word("cucumber", a) False # The excellent example from @OmPrakash >>> find_only_whole_word("is", "this isis a sample") False >>>
Ответ 4
Проблема с регулярными выражениями заключается в том, что если строка, которую вы хотите найти в другой строке, содержит символы регулярных выражений, это усложняется. любая строка со скобками завершится ошибкой.
Этот код найдет слово
word="is" srchedStr="this is a sample" if srchedStr.find(" "+word+" ") >=0or \ srchedStr.endswith(" "+word): <do stuff>
Первая часть условия выполняет поиск текста с пробелом с каждой стороны, а вторая часть улавливает ситуацию конца строки. Обратите внимание, что endwith является логическим значением, тогда как find возвращает целое число