匹配除某些特殊字符和“:)”以外的所有字符的正则表达式

8
我试图从字符串中删除除 #, @, :), :( 之外的所有字符。 示例:
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

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


1
你能提供一个字符串示例,说明你想要删除/保留哪些字符吗? - Anjani Dhrangadhariya
1
你可以只提取那些序列,而不是选择其他所有内容。 - ssc-hrep3
1
如果您确切地知道您的例外情况,实际上不需要使用环视。使用捕获机制,参见此答案以了解如何操作。 - Wiktor Stribiżew
4个回答

7

这是一个棘手的问题,因为您想要删除除某个特定白名单之外的所有符号。此外,白名单上的一些符号实际上包含两个字符:

:)
:(

为了处理这个问题,我们可以首先保留冒号:和括号,然后有选择性地删除它们中的一个,如果它不是笑脸或皱眉脸的一部分。
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:()@&#]

这将匹配任何非单词或空格字符。它还将豁免您的白名单,不进行替换。在备选项的另外两部分中,我们覆盖了此逻辑,通过删除冒号和括号,除非它们不是笑脸的一部分。


5

正如其他人所展示的那样,按照您所描述问题的方式编写正则表达式是可行的。但这是一种更简单的方法,可以编写一个匹配您想要保留的部分的正则表达式。然后将这些部分连接在一起即可。

import re

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

2
您可以尝试使用以下正则表达式(针对Python)。
(\w|:\)|:\(|#|@| )

用这个假句子:

"我想删除某些字符但想保留一些像 #random,和 :) 和 :( 和 @ 这样的。

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

它可以找到您在问题中提到的所有字符。 您可以使用它来查找包含它的字符串,并编写规则仔细删除此字符串中的其他标点符号。


1
您也可以采用简单的方法:匹配和捕获需要“排除”的内容,然后只匹配要删除的内容,最后使用反向引用来引用捕获组的值:
re.sub(r'([#@\s]|:[)(])|\W', r'\1', s)
#        ^---Group 1--^->->->->^^         

请查看正则表达式演示。 这里,([#@\s]|:[)(])匹配并捕获一个#@、空格字符或:():子字符串到第1组中,\W匹配但不捕获任何非单词字符。

请查看Python演示

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 @  #  :)

在Python 3.5之前的版本中,由于一个错误,请使用lambda表达式作为替换参数:
re.sub(r'([#@\s]|:[)(])|\W', lambda x: x.group(1) if x.group(1) else '', s)

所以 r'\1' 选择第一组? - mahmoudafer
1
@MaStErNeWbIe 在替换模式中的\1字符串将匹配的整个内容替换为第一组的内容。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接