我想要一个正则表达式模式来匹配笑脸 ":)" ,":(" 。它还应该捕获重复的笑脸,比如 ":) :)" , ":) :(" 但过滤掉无效的语法,比如 ":( (" .
我有这个,但它匹配 ":( ("
bool( re.match("(:\()",str) )
我可能在这里遗漏了一些明显的东西,对于这个看似简单的任务,我需要一些帮助。
我认为它最终“点击”了您在此处询问的内容。看看下面的内容:
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);
您的原始代码的问题是您的正则表达式是错误的:(:\()
. 让我们分解一下。
外括号是“分组”。如果您要进行字符串替换,它们就是您要参考的内容,并且用于一次将正则表达式运算符应用于字符组。所以,你真的是在说:
(
开始一个小组
:\(
...做正则表达式的东西...:
不是正则表达式保留字符,所以它只是一个冒号。\
是,它的意思是“以下字符是文字,而不是正则表达式运算符” 。这称为“转义序列”。完全解析成英文,你的正则表达式说
(
开始一个小组
:
冒号字符\(
左括号字符)
结束组我使用的正则表达式稍微复杂一些,但还不错。让我们分解一下:^(:\(|:\))+$
。
^
分别$
表示“行首”和“行尾”。现在我们有...
^
行首
(:\(|:\))+
...做正则表达式的东西...$
行结束...所以它只匹配构成整行的东西,而不是简单地出现在字符串的中间。
我们知道这一点(
并)
表示一个分组。+
意思是“其中一个”。现在我们有:
^
行首(
开始一个小组
:\(|:\)
...做正则表达式的东西...)
结束组+
匹配其中一项或多项$
行结束最后是|
(pipe) 运算符。它的意思是“或”。所以,应用我们从上面知道的转义字符,我们准备完成翻译:
^
行首(
开始一个小组
:
冒号字符\(
左括号字符|
或者
:
冒号字符\)
右括号字符)
结束组+
匹配其中一项或多项$
行结束我希望这有帮助。如果没有,请告诉我,我很乐意通过回复来编辑我的答案。
也许是这样的:
re.match('[:;][)(](?![)(])', str)
试试(?::|;|=)(?:-)?(?:\)|\(|D|P)
。尚未对其进行广泛测试,但似乎确实与正确的匹配,而不是更多...
In [15]: import re
In [16]: s = "Just: to :)) =) test :(:-(( ():: :):) :(:( :P ;)!"
In [17]: re.findall(r'(?::|;|=)(?:-)?(?:\)|\(|D|P)',s)
Out[17]: [':)', '=)', ':(', ':-(', ':)', ':)', ':(', ':(', ':P', ';)']
我从这里发布的评论和答案中得到了我正在寻找的答案。
re.match("^(:[)(])*$",str)
谢谢大家。