正则表达式如何匹配带有可选结束部分的语句?

时间:2016-03-27 07:12:52

标签: python regex

声明如:

[string1...] string2 in english/chinese (string3...)

string3在()中,是可选的。

我在python中写了一个正则表达式模式:

(\[(?P<string1>.*)\])\s*(?P<string2>.*)\s(\((?P<string3>.*)\))?

但是*是贪婪的匹配,而string3将在string2中解析。

我使用超前匹配string3,例如:

(\[(?P<string1>.*)\])\s*(?P<string2>.*(?=\())\s*((?P<string3>.*)\))?

但也不配。

如何获得三个匹配部分,最后一部分在()中是可选的?

3 个答案:

答案 0 :(得分:2)

您可以使用此正则表达式基于带锚$的否定模式:

\[(?P<string1>[^\]]*)\]\s*(?P<string2>[^()]*)(?:\s+\((?P<string3>.*)\))?$

这里我们使用了2个否定子模式:

[^\]]*  # matches 0 or more of any char that 
[^()]*  # matches 0 or more of any char that is not ( and )

RegEx Demo

答案 1 :(得分:2)

这样的东西?

^(?P<string1>\[[^]]+\])       # anchor it to the start
(?P<string2>[^(\n]+)          # everything not a (
(?:\((?P<string3>[^)]+)\))?$  # sth. in (), optional

使用multilineverbose模式,请参阅 a demo on regex101.com
Python

import re
string = "[string1...] string2 in english/chinese (string3...)"
rx = re.compile("""
    ^(?P<string1>\[[^]]+\])       # anchor it to the start
    (?P<string2>[^(\n]+)          # everything not a (
    (?:\((?P<string3>[^)]+)\))?$  # sth. in (), optional
""", re.MULTILINE|re.VERBOSE)
matches = rx.findall(string)

答案 2 :(得分:2)

在正则表达式中,我在\(之前看到string 3,这意味着字符串3包含在括号内。在这种情况下,您可以匹配string 2,直到找不到左括号。

正则表达式: (\[(?P<string1>.*?)\])\s*(?P<string2>[^\(]*)\s*(\((?P<string3>.*)\))?

注意组[^\(]

中的string2

<强> Regex101 Demo