在Python正则表达式中匹配Unicode表情符号

9

我需要在文本中提取数字和表情符号之间的文本

示例文本:

blah xzuyguhbc ibcbb bqw 2 extract1  ☺️ jbjhcb 6 extract2  bjvcvvv

输出:

extract1
extract2

我编写的正则表达式代码提取两个数字之间的文本,我需要更改它识别Unicode表情符号并提取它们之间的文本的部分。
(?<=[\s][\d])(.*?)(?=[\d])

请推荐一种适用于Python的方法,并且需要支持所有表情符号,而不仅仅是示例中的那些。

https://regex101.com/r/uT1fM0/1


你应该查看这个堆栈以获取表情符号的正则表达式 https://dev59.com/eofca4cB1Zd3GeqPeiDl - reticentroot
@reticentroot 我认为它不适用于像""这样的UTF8表情符号。 - Delgan
@reticentroot 我需要它能够处理Unicode表情符号。 - LeDerp
你能在匹配表情符号之前先将Unicode表情符号转换为文本吗?这篇帖子https://dev59.com/6l8e5IYBdhLWcg3wd6Q6可以实现。 - TuanDT
3个回答

7

由于表情符号具有不同的Unicode值,您必须在正则表达式中明确指定它们,或者如果它们处于特定范围,则可以使用字符类。 在这种情况下,您的第二个符号不是标准表情符号,而只是一个Unicode字符,但由于它大于\u263a(☺️的Unicode表示),因此您可以将其与\u263a放在一个范围内:

In [71]: s = 'blah xzuyguhbc ibcbb bqw 2 extract1  ☺️ jbjhcb 6 extract2  bjvcvvv'

In [72]: regex = re.compile(r'\d+(.*?)(?:\u263a|\U0001f645)')

In [74]: regex.findall(s)
Out[74]: [' extract1  ', ' extract2 ']

如果您想匹配更多的表情符号,可以使用字符范围(这里有一个好的参考网站,可以显示不同表情符号的正确范围 http://apps.timwhitlock.info/emoji/tables/unicode):

In [75]: regex = re.compile(r'\d+(.*?)[\u263a-\U0001f645]')

In [76]: regex.findall(s)
Out[76]: [' extract1  ', ' extract2 ']

请注意,在第二种情况下,您必须确保前述范围内的所有字符都是您想要的表情符号。
以下是另一个例子:
In [77]: s = "blah 4 xzuyguhbc  ibcbb bqw 2 extract1  ☺️ jbjhcb 6 extract2  bjvcvvv"

In [78]: regex = re.compile(r'\d+(.*?)[\u263a-\U0001f645]')

In [79]: regex.findall(s)
Out[79]: [' xzuyguhbc ', ' extract1  ', ' extract2 ']

我需要它能够处理所有的表情符号,而不仅仅是示例中提供的那些。 - LeDerp
如我所提到的,在这种情况下,您必须使用字符范围。 - Mazdak

2
这是我的解决方案,不确定是否适用于所有情况。诀窍在于将所有unicode表情符号转换为普通文本。可以按照这篇文章的方式进行操作。然后您就可以像匹配普通文本一样匹配表情符号了。请注意,如果您搜索的文本中包含字面字符串\u\U,则此方法将无法正常工作。
例如:将您的字符串复制到一个文件中,我们称之为emo。在终端中执行:
Chip chip@ 03:24:33@ ~: cat emo | python stackoverflow.py
blah xzuyguhbc ibcbb bqw 2 extract1  \u263a\ufe0f jbjhcb 6 extract2 \U0001f645 bjvcvvv\n
------------------------
[' extract1  ', ' extract2 ']

stackoverflow.py文件的位置:

import fileinput
a = fileinput.input();
for line in a:
    teststring = unicode(line,'utf-8')
    teststring = teststring.encode('unicode-escape')

import re
print teststring
print "------------------------"
m = re.findall('(?<=[\s][\d])(.*?)(?=\\\\[uU])', teststring)
print m

0

所以这可能会或不会根据您的需求工作。如果您事先知道表情符号,那么这可能有效,您只需要一个预期的表情符号类型列表。

无论如何,没有更多信息,这就是我要做的。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re

my_regex = re.compile(r'\d\s*([^☺️|^]+)')

string = "blah xzuyguhbc ibcbb bqw 2 extract1  ☺️ jbjhcb 6 extract2  bjvcvvv"

m = my_regex.findall(string)
if m:
  print m

然后你需要一个有效的列表,每个表情符号的模式都不同,这就像是说我需要匹配英语中的每个单词,而我需要一个正则表达式来完成。否则,考虑另一种模式,也许你知道在数字后面总是有一个单词,那么你可以说获取数字后面的下一个单词,并且不关心表情符号。 - reticentroot

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