Python regex, удалите все знаки препинания, кроме дефиса для строки unicode

У меня есть этот код для удаления всех знаков препинания из строки регулярного выражения:

import regex as re    
re.sub(ur"\p{P}+", "", txt)

Как я могу изменить его, чтобы разрешить дефис? Если бы вы могли объяснить, как вы это сделали, это было бы здорово. Я понимаю, что здесь, исправьте меня, если я ошибаюсь, P ни с чем после пунктуации.

Ответы

Ответ 1

[^\P{P}-]+

\P является дополнением к \P - а не пунктуацией. Таким образом, это соответствует любому, что не является (не пунктуация или тире), что приводит к всем пунктуациям, кроме тире.

Пример: http://www.rubular.com/r/JsdNM3nFJ3

Если вы хотите не запутанный способ, альтернативой является \p{P}(?<!-): сопоставить все знаки препинания, а затем проверить, что это не тире (используя отрицательный lookbehind).
Рабочий пример: http://www.rubular.com/r/5G62iSYTdk

Ответ 2

Здесь, как это сделать с модулем re, если вы должны придерживаться стандартных библиотек:

# works in python 2 and 3
import re
import string

remove = string.punctuation
remove = remove.replace("-", "") # don't remove hyphens
pattern = r"[{}]".format(remove) # create the pattern

txt = ")*^%{}[]thi - is - @@#!a !%%!!%- test."
re.sub(pattern, "", txt) 
# >>> 'this - is - a - test'

Если производительность имеет значение, вы можете использовать str.translate, так как быстрее, чем с использованием регулярного выражения. В Python 3 код txt.translate({ord(char): None for char in remove}).

Ответ 3

Вы можете либо указать пунктуацию, которую вы хотите удалить вручную, как в [._,], или поставить функцию вместо строки замены:

re.sub(r"\p{P}", lambda m: "-" if m.group(0) == "-" else "", text)