正则表达式匹配除复合词的连字符之外的非字母字符

时间:2018-03-16 10:31:54

标签: python regex python-3.6

python 3.6的正则表达式。我试图删除非字母字符,但我想在复合词中不匹配连字符。这是我的模式:

[^\sA-Za-z\u00C0-\u00FF\u0153\u0152-]|(?=\W)-(?<=\W)

例如对于- word-word我想匹配第一个 - 但不是第二个但我的模式匹配两者。

1 个答案:

答案 0 :(得分:1)

在Python 3.6中,您可以使用一种技术匹配并捕获您需要保留的内容(字母之间的-可以与[^\W\d_]-(?=[^\W\d_])匹配)匹配您需要删除的内容(所有非字母数字或您定义的任何字符)。

因此,示例re.sub看起来像

re.sub(r'([^\W\d_]-)(?=[^\W\d_])|[^\sA-Za-z\u00C0-\u00FF\u0153\u0152]', r'\1', s)

re.sub(r'([^\W\d_]-)(?=[^\W\d_])|(?:[^\w\s]|_)', r'\1', s)

,其中

  • ([^\W\d_]-)(?=[^\W\d_]) - 任何字母和-后面跟着任何字母(这是允许连续匹配的正向前瞻,例如a-b-c
  • | - 或
  • (?:[^\w\s]|_) - 任何单个非字和非空白字符或_都匹配。

r'\1'是替换反向引用,占位符引用组1中的内容,将其插回到结果字符串中。

请参阅regex demo

在3.5之前的Python版本中,您需要使用lambda作为替换参数来检查Group 1是否匹配:

re.sub(r'([^\W\d_]-)(?=[^\W\d_])|(?:[^\w\s]|_)', lambda x: x.group(1) if x.group(1) else '', s)

另一种可能的解决方案是

re.sub(r'(?!\b-\b)(?:[^\w\s]|_)', '', s)

请参阅regex demo。在这里,使用单词字符括起来的-将不会匹配\b字边界(但即使用下划线括起来也会避免匹配-。)