正则表达式:捕获可选的开始或结束组/子组

时间:2015-12-30 02:25:05

标签: python regex

我试图写一个正则表达式来查找字符串中的不同表情符号。一些表情符号有帽子[示例派对帽图释:*< :-)] 所以我试图在表达式的开头为帽子添加一个可选组。我遇到的问题是,当我将一个可选组添加到表达式的开头或结尾时,它开始匹配空字符串。我在这里阅读了关于这个主题的一些其他问题,但我仍然无法理解为什么会发生这种情况以及我可以采取哪些措施来解决这个问题。这就是我到目前为止所拥有的:

 r"""
 (                 
     ([{}]|K|(E-)|(\*<))?   # Optional Hat/Toupee
     [:;8B=xX#%*0]          # Eyes
     [-o]?                  # Optional Nose
     [DbP)(>{c$I3/\J&]      # Mouth/Tongue
 )"""

如果我尝试在字符串中匹配:-),则正则表达式解析器返回:

[(':-)', '', '', '')]

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

import re

message1 = "I'm happy today :-)"
message2 = 'Me too *<:-) :3'
message3 = 'I prefer emoticons like this: =D =) =P'

regexp = re.compile("(([{}*<]+)?[:;8B=xX#%*0][-o]?[DbP)(>{c$I3/\J&])")
emoticons1 = regexp.findall(message1)
emoticons2 = regexp.findall(message2)
emoticons3 = regexp.findall(message3)
print(emoticons1)
print(emoticons2)
print(emoticons3)

如果你想每个表情符号只有两次捕获,一个用于表情符号,另一个用于表情符号,你只需要两个组。

并且,在哪里:[DbP)(>{c$I3/\J&] 您无法在charclass中\使用\J。在charclass中,everthing是一个特征。如果您想获得J,则只能使用J

答案 1 :(得分:1)

每个括号对都会在表达式中添加一个捕获组。要调试正则表达式,请使用?P<name>

为捕获组命名
regexp = re.compile("(?P<A>(?P<B>[{}]|K|(?P<C>E-)|(?P<D>\*<))?[:;8B=xX#%*0][-o]?[DbP)(>{c$I3/\J&])")

然后你有:

>>> print regexp.match(':-)').groupdict()
{'A': ':-)', 'C': None, 'B': None, 'D': None}

这对我有意义。

请注意,除非您想要捕获表情符号的这些特定部分,否则C和D组对我来说不再必要。除非您想单独捕获帽子部分,否则可以使用(?:)代替()使B组无法捕获。