8

我想要一个正则表达式模式来匹配笑脸 ":)" ,":(" 。它还应该捕获重复的笑脸,比如 ":) :)" , ":) :(" 但过滤掉无效的语法,比如 ":( (" .

我有这个,但它匹配 ":( ("

bool( re.match("(:\()",str) ) 

我可能在这里遗漏了一些明显的东西,对于这个看似简单的任务,我需要一些帮助。

4

4 回答 4

8

我认为它最终“点击”了您在此处询问的内容。看看下面的内容:

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) 运算符。它的意思是“或”。所以,应用我们从上面知道的转义字符,我们准备完成翻译:

  • ^行首
  • (开始一个小组
    • :冒号字符
    • \(左括号字符
  • |或者
    • :冒号字符
    • \)右括号字符
  • )结束组
  • +匹配其中一项或多项
  • $行结束

我希望这有帮助。如果没有,请告诉我,我很乐意通过回复来编辑我的答案。

于 2013-02-01T18:15:11.993 回答
3

也许是这样的:

re.match('[:;][)(](?![)(])', str)
于 2013-01-28T21:05:41.350 回答
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', ';)']
于 2013-01-28T21:23:27.810 回答
0

我从这里发布的评论和答案中得到了我正在寻找的答案。

re.match("^(:[)(])*$",str)

谢谢大家。

于 2013-01-28T22:01:28.870 回答