提问者:小点点

用正则表达式在字符串中间匹配一个可选子串


我试图创建一个正则表达式提取标题,字幕和出版商。我想知道如何使字幕搜索可选。

Title-(Subtitle)-[Publisher]

哪里:

  • 标题-是我想在第一个捕获组中捕获的字符串。
  • (副标题)-是一个可选的字符串,由括号包围,我想在第二个捕获组中捕获。
  • [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个答案

匿名用户

只需使用将第二个捕获设置为可选即可

(.*?)-(?:\((.*?)\)-)?\[(.*?)\]
       ^^^         ^^

我还替换了**以避免贪婪。

匿名用户

贪婪匹配是一件好事,因为它允许更高效的正则表达式执行。

要享受性能优势并维护模式逻辑,请使用包含下一个预期定界字符的否定字符类。

([^-]*)-(?:\(([^)]*)\)-)?\[([^]]*)]

分解: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)