【问题标题】:Capturing emoticons using regular expression in python在python中使用正则表达式捕获表情符号
【发布时间】:2013-01-12 07:50:33
【问题描述】:

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

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

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

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

【问题讨论】:

  • :( ( 是无效的,还是有效和无效的组合?
  • 无效。只有笑脸和重复的笑脸才有效。
  • 那么您应该使用^$.. 指定整个字符串,因为它成功匹配字符串中的任何类似somewhere
  • 谢谢你..我错过了这一点。让我再试一次。

标签: python regex


【解决方案1】:

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

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);

您的原始代码的问题在于您的正则表达式错误:(:\()。让我们分解一下。

外括号是“分组”。如果您要进行字符串替换,它们就是您要引用的内容,并且用于一次将正则表达式运算符应用于字符组。所以,你真的是在说:

  • ( 开群
    • :\( ... 做正则表达式的东西 ...
  • ')' 结束组

: 不是正则表达式保留字符,所以它只是一个冒号。 \ 是,它的意思是“以下字符是文字​​,而不是正则表达式运算符”。这称为“转义序列”。完全解析成英文,你的正则表达式说

  • ( 开群
    • : 冒号
    • \( 左括号字符
  • )结束群

我使用的正则表达式稍微复杂一些,但还不错。让我们分解一下:^(:\(|:\))+$

^$ 分别表示“行首”和“行尾”。现在我们有...

  • ^ 行首
    • (:\(|:\))+ ... 做正则表达式的东西 ...
  • $ 行尾

...所以它只匹配构成整行的东西,而不是简单地出现在字符串的中间。

我们知道() 表示一个分组。 + 表示“其中之一”。现在我们有:

  • ^ 行首
  • (开群
    • :\(|:\) ... 做正则表达式的东西 ...
  • )结束群
  • + 匹配其中一项或多项
  • $ 行尾

最后是|(管道)运算符。它的意思是“或”。所以,应用我们从上面知道的转义字符,我们准备完成翻译:

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

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

【讨论】:

  • 谢谢。尽管我自己设法解决了这个问题,但您解释得非常清楚的答案帮助我清除了许多正则表达式概念。
  • 很高兴听到你把它处理好了,我很高兴我的解释有帮助:)
【解决方案2】:

我从此处发布的 cmets 和答案中得到了我正在寻找的答案。

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

谢谢大家。

【讨论】:

  • 此正则表达式仅在 str: 开头并且仅包含重复的 :):( 一直到末尾时才有效。你确定这是你要找的吗?
  • 是的,这正是我想要的。很抱歉无法正确地发布问题。并感谢您的回答。
  • 嗯...你确定你确定吗? :) 以下字符串将匹配此正则表达式::):):):):(:(:):(:)。从显示器的这一侧看,这似乎没有用。
  • 同样,空字符串匹配。 * 表示“零次或多次出现”。 + 表示“出现一次或多次”,? 表示“出现零次或一次”。
  • 是的,我同意这通常没有意义。但我用它来解决编程竞赛问题。
【解决方案3】:

试试(?::|;|=)(?:-)?(?:\)|\(|D|P)。尚未对其进行广泛测试,但似乎确实匹配正确的而不是更多...

In [15]: import re

In [16]: s = "Just: to :)) =) test :(:-(( ():: :):) :(:( :P ;)!"

In [17]: re.findall(r'(?::|;|=)(?:-)?(?:\)|\(|D|P)',s)
Out[17]: [':)', '=)', ':(', ':-(', ':)', ':)', ':(', ':(', ':P', ';)']

【讨论】:

  • 谢谢.. (?..) 是什么意思?我阅读了文档,但无法理解。如果你能稍微解释一下这个模式,我会很高兴..
【解决方案4】:

可能是这样的:

re.match('[:;][)(](?![)(])', str)

【讨论】:

  • urm..你能解释一下它到底是做什么的吗?
  • 此正则表达式将匹配;:,后跟)(,但仅当它后面没有另一个) 或@ 时987654327@。这可能不是完美的解决方案,但至少是看待问题的另一种方式。
猜你喜欢
  • 2021-10-27
  • 2014-08-27
  • 1970-01-01
  • 2017-01-24
  • 2018-07-21
  • 1970-01-01
  • 2016-07-19
  • 2015-05-31
相关资源
最近更新 更多