Вот регулярное выражение, которое может решить эту проблему:
Regex
(?<=[\W_]+|^)and(?=[\W_]+|$)
Пример
# import regex
string = 'this_And'
test = regex.search(r'(?<=[\W_]+|^)and(?=[\W_]+|$)', string.lower())
print(test.group(0))
# prints 'and'
# No match
string = 'Andy'
test = regex.search(r'(?<=[\W_]+|^)and(?=[\W_]+|$)', string.lower())
print(test)
# prints None
strings = [ "this_and", "this.and", "(and)", "[and]", "and^", ";And"]
[regex.search(r'(?<=[\W_]+|^)and(?=[\W_]+|$)', s.lower()).group(0) for s in strings if regex.search(r'(?<=[\W_]+|^)and(?=[\W_]+|$)', s.lower())]
# prints ['and', 'and', 'and', 'and', 'and', 'and']
Объяснение
[\W_]+
означает, что мы принимаем до (?<=
) или после (?=
) and
только несловарные символы, кроме знака подчеркивания _
(символ слова, который) принимается. |^
и |$
позволяют совпадениям лежать на краю строки.
Редактировать
Как уже упоминалось в моем комментарии, модуль regex
не дает ошибок с переменной длиной взгляда (в отличие от re
).
# This works fine
# import regex
word = 'and'
pattern = r'(?<=[\W_]+|^){}(?=[\W_]+|$)'.format(word.lower())
string = 'this_And'
regex.search(pattern, string.lower())
Однако, если вы настаиваете на использовании re
, то в верхней части моей головы я бы посоветовал разделить взгляд сзади на два (?<=[\W_])and(?=[\W_]+|$)|^and(?=[\W_]+|$)
, чтобы также регистрировались случаи, когда строка начинается с and
.
# This also works fine
# import re
word = 'and'
pattern = r'(?<=[\W_]){}(?=[\W_]+|$)|^{}(?=[\W_]+|$)'.format(word.lower(), word.lower())
string = 'this_And'
re.search(pattern, string.lower())