R中已经有一个接近的答案gsub("[^[:alnum:]['-]", " ", my_string),但是在Python中不起作用:
my_string = 'compactified on a calabi-yau threefold @ ,.'
re.sub("[^[:alnum:]['-]", " ", my_string)
Run Code Online (Sandbox Code Playgroud)
给 'compactified on a calab yau threefold @ ,.'
因此,它不仅删除了单词内的破折号,而且还删除了破折号之前单词的最后一个字母。而且它不会删除标点符号
预期结果(字符串,不带标点,但单词内用短划线表示): 'compactified on a calabi-yau threefold'
R根据perl选项(或使用的功能)使用TRE(POSIX)或PCRE正则表达式引擎。Python使用经过修改的,比Perl更差的版本作为re库。Python不支持POSIX字符类,因为[:alnum:]它与alpha(字母)和num(数字)匹配。
在Python中,[:alnum:]可以用[^\W_](或仅ASCII [a-zA-Z0-9])替换,而取反[^[:alnum:]]-可以用[\W_]([^a-zA-Z0-9]仅ASCII版本)替换。
所述[^[:alnum:]['-]匹配比字母数字之外的任何1个符号(字母或数字), ,[,'或-。这意味着您引用的R问题不能提供正确的答案。
您可以使用以下解决方案:
import re
p = re.compile(r"(\b[-']\b)|[\W_]")
test_str = "No - d'Ante compactified on a calabi-yau threefold @ ,."
result = p.sub(lambda m: (m.group(1) if m.group(1) else " "), test_str)
print(result)
Run Code Online (Sandbox Code Playgroud)
在(\b[-']\b)|[\W_]正则表达式匹配和捕获intraword -和'我们在恢复它们re.sub通过检查捕获组匹配,并重新插入它m.group(1),其余的(所有非字字符和下划线),只是用空格代替。
如果要删除一个空格的非单词字符序列,请使用
p = re.compile(r"(\b[-']\b)|[\W_]+")
Run Code Online (Sandbox Code Playgroud)