Вы должны спросить себя, какие шаблоны соответствуют любым символам из смайликов, которые вы хотите "защитить".Вы можете легко увидеть, что r"[^A-Za-z0-9(),!?'`]"
, r"\("
и r"\)"
соответствуют этим символам.
Таким образом, вы можете исправить этишаблоны:
s = re.sub(r":-?[()]|([^A-Za-z0-9(),!?'`])", lambda x: " " if x.group(1) else x.group(), s) # Match smilies and match and capture what you need to replace
s = re.sub(r"(?<!:)(?<!:-)\(", " ", s) # Prepend (?<!:)(?<!:-) lookbehinds
s = re.sub(r"(?<!:)(?<!:-)\)", " ", s) # Prepend (?<!:)(?<!:-) lookbehinds
Шаблон :-?[()]|([^A-Za-z0-9(),!?'`])
соответствует смайлику для защиты (:-?[()]
соответствует :
, затем необязательный -
и затем (
или )
) или соответствуети захватывает в группу 1 любой символ, отличный от определенного в классе отрицанных символов.Лямбда-выражение lambda x: " " if x.group(1) else x.group()
реализует пользовательскую логику замены в зависимости от совпадения группы: если сопоставляется Группа 1, замена происходит, в противном случае смайлик возвращается на прежнее место.
Отрицательный взгляд (?<!:)(?<!:-)
делаетубедитесь, что (
и )
не совпадают, если к ним добавляется :
или :-
.
Примечание r'\S*(x{2,}|X{2,})\S*'
также может соответствовать смайликам, если они приклеены кxx
или XX
.Однако исправить это довольно сложно, поскольку :(
как смайлики могут совпадать с \S*
, если они не находятся в начале блока без пробелов, поэтому вы можете использовать
s = re.sub(r'(:-[()])|(?:(?!:-?[()])\S)*(?:x{2,}|X{2,})(?:(?!:-?[()])\S)*',"xxx" if x.group(1) else x.group(), s)
Тактикааналогичен шаблону r":-?[()]|([^A-Za-z0-9(),!?'`])"
, мы сопоставляем и фиксируем смайлик, но затем разрешаем сопоставлять только такие символы без пробелов (\S
), которые не запускают подстроку смайлика ((?:(?!:-?[()])\S)*
).