Вы можете использовать
pat = r'(?!(?<=[A-Za-z])[A-Za-z])(?:{})(?<![A-Za-z](?=[A-Za-z]))'.format("|".join([re.escape(x) for x in v]))
См. онлайн-демонстрацию регулярных выражений .
Главное здесь - это обходные пути, (?!(?<=[A-Za-z])[A-Za-z])
и (?<![A-Za-z](?=[A-Za-z]))
.
(?!(?<=[A-Za-z])[A-Za-z])
- это отрицательный запрос, который не соответствует совпадению, если непосредственно справа от текущего местоположения (т. Е. Первый символ ключевого слова) является буквой ASCII, которой предшествует другая буква ASCII (проверяется с помощьюположительный lookbehind (?<=[A-Za-z])
).
(?<![A-Za-z](?=[A-Za-z]))
является отрицательным lookbehind, который не может найти совпадение, если непосредственно слева от текущего местоположения (т.е. последний символ ключевого слова) является буквой ASCII, котораясопровождается еще одной буквой ASCII (проверяется положительным символом (?=[A-Za-z])
).
Обратите внимание, что вам не нужно добавлять эти обходные пути к каждой альтернативе в регулярном выражении, просто используйте их, чтобы заключить (?:...|...)
какгруппа альтернатив, которую вы можете построить динамически, как я показал выше.
Также, [re.escape(x) for x in v]
удобно, если любое из ключевых слов может содержать специальные символы регулярного выражения, которые следует рассматривать как liтеральные символы.
Демо Python :
import re
s = 'BEAUTY Company is good, 歡迎~~YOU, SALE'
v = ['BEA','Com','歡迎','SALE']
pat = r'(?!(?<=[A-Za-z])[A-Za-z])(?:{})(?<![A-Za-z](?=[A-Za-z]))'.format("|".join([re.escape(x) for x in v]))
print(re.findall(pat, s)) # => ['歡迎', 'SALE']