在Python中使用正则表达式捕获表情符号
我想要一个正则表达式,用来匹配表情符号,比如 ":)" 和 ":("。它还应该能够识别重复的表情,比如 ":) :)" 和 ":) :(",但要过滤掉无效的写法,比如 ":( ("。
我现在有一个正则表达式,但它却匹配到了 ":( ("。
bool( re.match("(:\()",str) )
我可能漏掉了一些明显的东西,希望能有人帮我解决这个看似简单的问题。
4 个回答
2
试试这个表达式 (?::|;|=)(?:-)?(?:\)|\(|D|P)
。我没有做过很多测试,但看起来它能匹配到正确的内容,而不会多匹配其他的...
In [15]: import re
In [16]: s = "Just: to :)) =) test :(:-(( ():: :):) :(:( :P ;)!"
In [17]: re.findall(r'(?::|;|=)(?:-)?(?:\)|\(|D|P)',s)
Out[17]: [':)', '=)', ':(', ':-(', ':)', ':)', ':(', ':(', ':P', ';)']
3
也许可以这样做:
re.match('[:;][)(](?![)(])', str)
9
我想我终于明白你在问什么了。看看下面的内容:
import re
smiley_pattern = '^(:\(|:\))+$' # matches only the smileys ":)" and ":("
def test_match(s):
print 'Value: %s; Result: %s' % (
s,
'Matches!' if re.match(smiley_pattern, s) else 'Doesn\'t match.'
)
should_match = [
':)', # Single smile
':(', # Single frown
':):)', # Two smiles
':(:(', # Two frowns
':):(', # Mix of a smile and a frown
]
should_not_match = [
'', # Empty string
':(foo', # Extraneous characters appended
'foo:(', # Extraneous characters prepended
':( :(', # Space between frowns
':( (', # Extraneous characters and space appended
':((' # Extraneous duplicate of final character appended
]
print('The following should all match:')
for x in should_match: test_match(x);
print('') # Newline for output clarity
print('The following should all not match:')
for x in should_not_match: test_match(x);
你原来的代码有问题,主要是你的正则表达式写错了:(:\()
。我们来分析一下。
外面的括号是一个“分组”。如果你要替换字符串时会用到它们,它们可以让你一次性对一组字符应用正则表达式的操作。所以,你实际上是在说:
(
开始一个分组:\(
... 进行正则表达式操作 ...
- ')' 结束这个分组
这里的:
并不是正则表达式中的特殊字符,所以它只是一个冒号。而\
是一个特殊字符,它的意思是“接下来的字符是字面意思,不是正则表达式的操作符”。这叫做“转义序列”。把你的正则表达式完全翻译成中文,就是:
(
开始一个分组:
一个冒号字符\(
一个左括号字符
)
结束这个分组
我用的正则表达式稍微复杂一点,但也不难。我们来分析一下:^(:\(|:\))+$
。
^
和$
分别表示“行的开始”和“行的结束”。现在我们有了:
^
行的开始(:\(|:\))+
... 进行正则表达式操作 ...
$
行的结束
... 所以它只匹配整行的内容,而不是字符串中间的部分。
我们知道(
和)
表示一个分组。+
的意思是“一个或多个”。现在我们有:
^
行的开始(
开始一个分组:\(|:\)
... 进行正则表达式操作 ...
)
结束这个分组+
匹配一个或多个这样的内容$
行的结束
最后,还有|
(管道符)操作符。它的意思是“或者”。所以,结合我们之前学到的转义字符,我们可以完成翻译:
^
行的开始(
开始一个分组:
一个冒号字符\(
一个左括号字符
|
或者:
一个冒号字符\)
一个右括号字符
)
结束这个分组+
匹配一个或多个这样的内容$
行的结束
希望这对你有帮助。如果没有,请告诉我,我会很乐意修改我的回答。