python 3.6的正则表达式。我试图删除非字母字符,但我想在复合词中不匹配连字符。这是我的模式:
[^\sA-Za-z\u00C0-\u00FF\u0153\u0152-]|(?=\W)-(?<=\W)
例如对于- word-word
我想匹配第一个 - 但不是第二个但我的模式匹配两者。
答案 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
字边界(但即使用下划线括起来也会避免匹配-
。)