【问题标题】:Matching an optional substring in the middle of the string with a regex将字符串中间的可选子字符串与正则表达式匹配
【发布时间】:2014-03-13 16:43:13
【问题描述】:

我正在尝试创建一个正则表达式来提取标题、副标题和出版商。我想知道如何使字幕搜索成为可选。

我的格式是:

Title-(Subtitle)-[Publisher]

地点:

  • 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]

现在,我有一个正则表达式 (see online) 将捕获第一个和第三个:

(.*)-\((.*)\)-\[(.*)\]

我的问题是我不知道如何构造一个匹配第二行的正则表达式(第 1 组中的标题,第 2 组应为空,第 3 组为 Publisher)如果它没有字幕括在括号中。这可以在单个正则表达式中完成吗?

【问题讨论】:

    标签: python regex


    【解决方案1】:

    只需使用? 将第二次捕获设为可选

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

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

    【讨论】:

    • 这行不通,除非你让第一个 * 不贪婪。
    • 感谢您的快速回答。它工作得很好! :) 另外,感谢@bj0 的好提示!
    【解决方案2】:

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

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

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

    故障:Python Regex Demo

    (          #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)
    

    【讨论】:

      猜你喜欢
      • 2022-01-17
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      相关资源
      最近更新 更多