3

我希望能够按照以下格式解析来自服务器控制台(Multicraft)的行:

"source" <[ignore]"username"> "message"

下面是一个聊天的例子:

[Server] <Johndonne> hello everyone!
[Chat] <[VIP][Owner]bit2shift> hey
[Chat] <[Mod]waisman> hello there
[Chat] <[Builder]bluesniper> hey john xD

我的第一个策略是使用这个正则表达式:

^(?P<source>\[[^\]]+\])?\s*<\[.+\](?P<sender>[^>]*)>\s*(?P<message>.*)$

但如果用户名前没有 [tag] 则失败,例如文本字符串为:

[Server] <Johndonne> hello everyone!

为了测试正则表达式,我使用了 re.findall(regex, line) 来获取带有参数的元组。有任何想法吗?

4

2 回答 2

3

您可以通过在其周围放置一个零或一量词 ( ?) 来使该部分成为可选,如下所示:

^(?P<source>\[[^\]]+\])?\s*<(?:\[[^\]]+\])?(?P<sender>[^>]*)>\s*(?P<message>.*)$

但是当输入字符串为 时,此模式将[Owner]bit2shift在组中捕获。您可能希望使用零个或多个量词 ( ) 对多个标签进行分组:<sender>[Chat] <[VIP][Owner]bit2shift> hey*

^(?P<source>\[[^\]]+\])?\s*<(?:\[[^\]]+\])*(?P<sender>[^>]*)>\s*(?P<message>.*)$

这将仅bit2shift<sender>组中捕获。

于 2013-09-04T22:25:27.780 回答
1

使其成为可选:

In [23]: x = """[Server] <Johndonne> hello everyone!
[Chat] <[VIP][Owner]bit2shift> hey
[Chat] <[Mod]waisman> hello there
[Chat] <[Builder]bluesniper> hey john xD"""

In [24]: rx = re.compile('^(?P<source>\[[^\]]+\])?\s*<(?:\[.+\])?(?P<sender>[^>]*)>\s*(?P<message>.*)$')

In [25]: [rx.search(xi) for xi in x.split('\n')]
Out[25]:
[<_sre.SRE_Match at 0x6c3ba48>,
 <_sre.SRE_Match at 0x6c3b7e8>,
 <_sre.SRE_Match at 0x6c3bae0>,
 <_sre.SRE_Match at 0x6c3bb78>]

In [26]: [rx.search(xi).group() for xi in x.split('\n')]
Out[26]:
['[Server] <Johndonne> hello everyone!',
 '[Chat] <[VIP][Owner]bit2shift> hey',
 '[Chat] <[Mod]waisman> hello there',
 '[Chat] <[Builder]bluesniper> hey john xD']
于 2013-09-04T22:25:39.293 回答