RegEx 用于匹配除一些特殊字符和“:)”之外的所有字符

Posted

技术标签:

【中文标题】RegEx 用于匹配除一些特殊字符和“:)”之外的所有字符【英文标题】:RegEx for matching all chars except some special chars and ":)" 【发布时间】:2019-09-29 04:35:31 【问题描述】:

我正在尝试从字符串中删除除#@:):( 之外的所有字符。 示例:

this is, a placeholder text. I wanna remove symbols like ! and ? but keep @ & # & :)

应该导致(删除匹配结果后):

this is a placeholder text I wanna remove symbols like  and  but keep @  #  :)

我试过了:

(?! |#|@|:\)|:\()\W

它正在工作,但在:):( 的情况下,: 仍在匹配中。 我知道它是匹配的,因为它会检查每个字符和之前的字符,例如::) 仅匹配 ::)) 匹配 :)

【问题讨论】:

您能否提供一个示例字符串,您想从中删除/保留某些字符? 您可以只提取这些序列而不是选择其他所有内容。 您实际上不需要使用环视,以防您确切知道您的异常。使用捕获机制,参见this answer 展示如何。 【参考方案1】:

您可以尝试以下正则表达式(适用于 Python)。

(\w|:\)|:\(|#|@| )

用这句假话:

“我想删除某些字符,但想保留某些字符,例如 #random、:) 和 :( 以及诸如 @ 之类的东西。

如果在另一个句子中找到它,:),请搜索它:( "

它会找到您在问题中提到的所有字符。您可以使用它来查找包含它的字符串并编写规则以小心地从该字符串中删除其他标点符号。

【讨论】:

【参考方案2】:

这是一个棘手的问题,因为您想删除除某个白名单之外的所有符号。另外,白名单上的一些符号实际上是由两个字符组成的:

:)
:(

要处理这个问题,我们可以先保留冒号: 和括号,然后如果它不是笑脸或皱眉脸的一部分,则有选择地删除其中一个:

input = "this is, a (placeholder text). I wanna remove symbols like: ! and ? but keep @ & # & :)"
output = re.sub(r'[^\w\s:()@&#]|:(?![()])|(?<!:)[()]', '', input)
print(output)

this is a placeholder text I wanna remove symbols like  and  but keep @ & # & :)

我使用的正则表达式字符类是:

[^\w\s:()@&#]

这将匹配任何不是单词或空白字符的字符。它还可以使您的白名单免于替换。在交替的其他两个部分中,我们通过删除冒号和括号来覆盖这个逻辑,如果它们不是是笑脸的一部分。

【讨论】:

【参考方案3】:

正如其他人所展示的那样,编写一个正则表达式是可能的,它将成功地解决您提出问题的方式。但在这种情况下,编写一个正则表达式来匹配您想要保留的内容要简单得多。然后将这些部分连接在一起。

import re

rgx = re.compile(r'\w|\s|@|&|#|:\)|:\(')
orig = 'Blah!! Blah.... ### .... #@:):):) @@ Blah! Blah??? :):)#'
new = ''.join(rgx.findall(orig))
print(new)

【讨论】:

【参考方案4】:

您也可以使用一种简单的方法:匹配并捕获您需要从匹配中“排除”的内容并仅匹配您要删除的内容,然后只需使用对捕获组值的反向引用:

re.sub(r'([#@\s]|:[)(])|\W', r'\1', s)
#        ^---Group 1--^->->->->^^         

请参阅regex demo。 在这里,([#@\s]|:[)(]) 匹配并 捕获 到第 1 组 a #@、空白字符或 :(:( 子字符串和 \W 匹配而不捕获任何非单词字符.

见Python demo:

import re
s="this is, a placeholder text. I wanna remove symbols like ! and ? but keep @ & # & :)"
print(re.sub(r'([#@\s]|:[)(])|\W', r'\1', s))
# => this is a placeholder text I wanna remove symbols like  and  but keep @  #  :)

在 3.5 之前的 Python 版本中,使用 lambda 表达式作为替换参数(由于错误):

re.sub(r'([#@\s]|:[)(])|\W', lambda x: x.group(1) if x.group(1) else '', s)

【讨论】:

所以 r'\1' 选择第 1 组? @MaStErNeWbIe \1 替换模式中的字符串将整个匹配替换为第 1 组的内容。

以上是关于RegEx 用于匹配除一些特殊字符和“:)”之外的所有字符的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式,匹配除 \r \n 之外的所有内容作为普通字符

Groovy:RegEx用于匹配字母数字和下划线和短划线

RegEx表示字符串中的N个空格

正则表达式:匹配除特定模式之外的所有内容

正则表达式 - 如何匹配除特定模式之外的所有内容

RegEx(在 JavaScript 中查找/替换) - 匹配非字母数字字符但忽略 - 和 +