用正则表达式匹配字符串中间的可选子串
我正在尝试创建一个正则表达式,用来提取标题、副标题和出版社。我想知道怎么让副标题的搜索变成可选的。
我的格式是:
Title-(Subtitle)-[Publisher]
其中:
- 标题 – 是我想在第一个捕获组中提取的字符串。
- (副标题)– 是一个可选的字符串,用括号括起来,我想在第二个捕获组中提取。
- [出版社] – 是一个用方括号括起来的字符串,我想在第三个捕获组中提取。
举个例子:
Programming.in.Python.3-(A.Complete.Introduction.to.the.Python.Language)-[Addison-Wesley]
Learning.Python-[O'Reilly]
Flask.Web.Development-(Developing.Web.Applications.with.Python)-[O'Reilly]
现在,我有一个正则表达式(在线查看),可以提取第一个和第三个部分:
(.*)-\((.*)\)-\[(.*)\]
我的问题是,我不知道怎么构建一个正则表达式,能够匹配第二行(标题在第一个组,第二个组应该是空的,第三个组是出版社),如果没有用括号括起来的副标题。这能在一个正则表达式中完成吗?
2 个回答
0
贪婪匹配是个好东西,因为它能让正则表达式的执行更高效。
为了享受这种性能上的好处,同时保持模式的逻辑,可以使用否定字符类,这种字符类里包含了接下来预期的分隔符字符。
([^-]*)-(?:\(([^)]*)\)-)?\[([^]]*)]
详细解析:Python 正则表达式示例
( #start capture group 1
[^-]* #match zero or more non-hyphen characters
) #end capture group 1
- #match literal hyphen
(?: #start non-capturing group
\( #match literal opening parenthesis
( #start capture group 2
[^)]* #match zero or more non-closing-parentheses
) #end capture group 2
\) #match literal closing parenthesis
- #match literal hyphen
) #end non-capturing group
? #make non-capturing group optional (zero or one occurrence)
\[ #match literal opening brace
( #start capture group 3
[^]]* #match zero or more non-closing brace characters (no escaping needed)
) #close capture group 3
] #match literal closing brace (no escaping needed)
4
只需让第二个捕获变成可选的,使用 ?
就可以了。
(.*?)-(?:\((.*?)\)-)?\[(.*?)\]
^^^ ^^
另外,我把 .*
替换成了 .*?
,这样可以避免贪婪匹配。