【问题标题】:Python3 regex: Keep some Emojis, discard the restPython3 正则表达式:保留一些表情符号,丢弃其余的
【发布时间】:2019-08-03 13:45:59
【问题描述】:

这里是菜鸟。我有字符串,我想保留一些表情符号并丢弃其余的。

输入:

这本书太有趣了❤️。这本书 ????是炸弹(最好的 在世界上 ???? ?????? )我爱 ???? ??? ???它!我绝对推荐它!'

期望的输出:

这本书太有趣了❤️。这本书是炸弹(最好的 在世界上)我爱???? ??? ???它!我绝对推荐它!'

我有匹配的 re.compile:

我不知道如何在 re.compile 中将其组合在一起,以排除另一个。或者保留字母数字、标点符号和我的表情符号,并将其余部分替换为“”。

mytext = This book is so funny❤️. This book ???? is the bomb(AS IN THE BEST 
IN THE WORLD ???? ???????? )I love ???? ???? ???? it!I definitely recommend it!'
# Desired out put:
# u'This book is so funny❤️. This book is the bomb(AS IN THE BEST 
IN THE WORLD )I love ???? ???? ???? it!I definitely recommend it!'
print ("Original text:")
print (mytext, "\n")

# Strip out emoticon modifiers, leaving a simplified emoticon to work with.
# https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block)
# https://en.wikipedia.org/wiki/Variation_Selectors_Supplement
Emoji_Modifiers = re.compile(u'([\U0000FE00-\U0000FE0F])|([\U000E0100-\U000E0100])')
mytext_mod_gone = Emoji_Modifiers.sub(r'', mytext) 
print ("Modifiers Removed:")
print (mytext_mod_gone, "\n")

# All emoticons    
find_regex      = re.compile(u'([\U00002600-\U000027BF])|([\U0001f300-\U0001f64F])|([\U0001f680-\U0001f6FF])')
# Heart emoticons
#find_regex     = re.compile(u"([\U00002619])|([\U00002661])|([\U00002665])|([\U00002763])|([\U00002764])|([\U00002765])|([\U00002766])|([\U00002767])|([\U00002E96])|([\U00002E97])|([\U00002F3C])|([\U0001F394])|([\U0001F48C])|([\U0001F48F])|([\U0001F491])|([\U0001F493])|([\U0001F494])|([\U0001F495])|([\U0001F496])|([\U0001F497])|([\U0001F498])|([\U0001F499])|([\U0001F49A])|([\U0001F49B])|([\U0001F49C])|([\U0001F49D])|([\U0001F49E])|([\U0001F49F])|([\U0001F4D6])|([\U0001F5A4])|([\U0001F60D])|([\U0001F618])|([\U0001F63B])|([\U0001F970])|([\U0001F9E1])")
# Alphanumeric + punctuation for an alternative solution
#find_regex     = re.compile(r"[^a-zA-Z0-9!,.?!#&'()*+,-./:;<=>?@\^_`{|}~\s]") # 

mytext_emoji_gone = find_regex.sub(r'', mytext)

我跌倒在:

  • 使用负后向 (?&lt;!...) 否定 unicode。我不太了解操作数,regex101.com 只适用于 r',而不适用于 u'。
  • 在 re.compile 中将多个正则表达式组合在一起。假设我想保留字母数字和我的表情符号,当我这样做时它会抱怨re.compile(u'(\Uxxxx)' | r'(regex)' )。 | 不支持的操作数类型:“str”和“str”,因此 OR 类型语句在此处不起作用……并且 OR 会产生不希望的结果。

我能提供一些帮助吗:

  • 忽略表情符号子集并删除其余表情符号(我的首选解决方案)
  • 保留(字母数字、标点符号和我的表情符号),并删除其余部分。
  • 一个具体的问题:你能“堆栈”重新编译吗? IE 创建 2 个不同的 re.compiles 来匹配(或不匹配)事物,然后将它们连接在一起。

【问题讨论】:

  • 实际上,你使用了错误的正则表达式来匹配表情符号,你匹配了很多其他的东西,而不仅仅是表情符号,你错过了很多包含超过 2 个字节的表情符号。当您使用 Python 3.x 时,您应该丢弃 u 前缀,默认情况下所有字符串都是 UTF8 字符串。为了解决这个问题,请使用负前瞻
  • regex101.com/r/rwTlgF/1, '(?![\U00002619\U00002661\U00002665\U00002763\U00002764\U00002765\U00002766\U00002767\U00002E96\U00002E97\U00002F3C\U0001F394\U0001F48C\U0001F48F\U0001F491\U0001F493\U0001F494\U0001F495\U0001F496\U0001F497\U0001F498\U0001F499\U0001F49A\U0001F49B\U0001F49C\U0001F49D\U0001F49E\U0001F49F\U0001F4D6\U0001F5A4\U0001F60D\U0001F618\U0001F63B\U0001F970\U0001F9E1])[\U00002600-\U000027BF\U0001f300-\U0001f64F\U0001f680-\U0001f6FF]'
  • @WiktorStribiżew。也许我在想这个错误。我真的只想要我的表情符号、字母数字和标点符号。我可以将我的表情符号的负面预测与字母数字标点符号结合起来。如果有 2 字节的表情符号并且匹配,那么我认为这种情况将很少见。他们肯定会脱颖而出。我可以将它们粘贴到谷歌表格中,并在那里使用 unicode 函数来查找它们的代码,然后编写一些 python 来捕获它们。感谢您提供负面的前瞻性示例。我现在就测试一下
  • Emooji v12.0,例如#391*男子举重*。查看它包含多少字节。您的表情符号正则表达式只会匹配其中的一小部分。

标签: regex python-3.x emoji regex-negation python-unicode


【解决方案1】:

regex101 有一个 Unicode 选项,它是一个可以从正则表达式框右侧打开的标志。

我认为最简单的方法是找到字符串中的所有表情符号,除了你想要保留的表情符号,然后用你想做的空字符串替换它们。为此,您可以使用可以找到任何表情符号的正则表达式(在此示例中,我将使用[\U00010000-\U0010ffff],但我确信那里有更好的,所以使用其中一个)并添加一个否定的前瞻性来忽略您希望保留的表情符号。

最后的正则表达式应该类似于this:

(?![\u2764])[\U00010000-\U0010ffff]

第一部分 (?![\u2764]) 将确保匹配不是您希望保留的表情符号,第二部分 [\U00010000-\U0010ffff] 将确保它是表情符号

您可以在方括号(?![\u2764 中添加您希望保留的所有其他表情符号 这里])

【讨论】:

  • “Unicode 选项”与 OP 使用的 u 字符串文字前缀无关。无需注意,u 在 OP 代码中是多余的。如果 OP 使用正确的 emoji 正则表达式,如果否定的 emoji 是更长允许的 emoji 的起始部分,则否定前瞻可能会失败。
  • @WiktorStribiżew 关于“Unicode 选项”的部分只是为了回应 OP 说 regex101 没有“Unicode 选项”我同意这不会帮助 OP 解决他的问题但是我觉得很高兴知道。如果您认为我应该删除它,我会这样做。关于较长表情符号的负面前瞻性否定部分:你确定吗?我认为正则表达式将整个表情符号视为一个字符,因此不会有问题
  • @WiktorStribiżew 你能解释一下关于更长时间允许的表情符号的“失败”吗?它会匹配我的表情符号和更长的表情符号,还是两者都不匹配导致它们被删除?
  • @GiladShnoor 啊,感谢右侧的 regex101 unicode 标志 :) 感谢您展示了将 unicode 放入负前瞻中的正确语法。今天要尝试的新事物 :) 感谢您和 Wiktor 对新手的帮助。
【解决方案2】:

我去了:

find_regex     = re.compile(u"(?![\U00002619])(?![\U00002661])(?![\U00002665])(?![\U00002763])(?![\U00002764])(?![\U00002765])(?![\U00002766])(?![\U00002767])(?![\U00002E96])(?![\U00002E97])(?![\U00002F3C])(?![\U0001F394])(?![\U0001F48C])(?![\U0001F48F])(?![\U0001F491])(?![\U0001F493])(?![\U0001F494])(?![\U0001F495])(?![\U0001F496])(?![\U0001F497])(?![\U0001F498])(?![\U0001F499])(?![\U0001F49A])(?![\U0001F49B])(?![\U0001F49C])(?![\U0001F49D])(?![\U0001F49E])(?![\U0001F49F])(?![\U0001F4D6])(?![\U0001F5A4])(?![\U0001F60D])(?![\U0001F618])(?![\U0001F63B])(?![\U0001F970])(?![\U0001F9E1])"r"[^a-zA-Z0-9!,.?!#&'()*+,-./:;<=>?@\^_`{|}~\s]")

mytext_emoji_gone = find_regex.sub(r'', mytext)

去除了所有其他表情符号,只留下了心形和书本表情符号,以及字母数字和标点符号。

作为我最初问题的一部分,有没有办法堆叠这些?目前,这是一大行代码。我们可以这样做:

regex = re.compile(a)
regex += re.compile(b)

这将使用垂直房地产,但我可以接受

【讨论】:

  • 您应该避免在回答中提出单独的问题。如果您有其他与您的问题相关的较小问题,您可以将其添加为评论、edit to your questionnew question,并引用此问题。
  • 在你的情况下,这里已经有了答案:stackoverflow.com/questions/33211404/…
  • 我还发现了变音符号,必须在删除其他所有内容之前将其删除。看到这个答案,创造奇迹:) stackoverflow.com/questions/517923/…
  • @Hoppeduppeanut 不完全-我的问题在那里没有得到回答。这与使用字符串或 re.verbose 的多行编辑有关。而我想知道 my original question 是否可以将 2 个 re.compiles 添加在一起。事后看来,我应该在原始问题中添加我的 regex =+ re.compile(b) 示例,以使我的问题更清楚。
猜你喜欢
  • 2022-10-14
  • 2017-02-21
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2021-11-15
  • 1970-01-01
相关资源
最近更新 更多