首页 > 解决方案 > 正则表达式将匹配项存储在错误的捕获组中

问题描述

我正在尝试构建一个带有可选捕获组的 python 正则表达式。我的正则表达式适用于大多数情况,但未能将匹配项放在一个测试用例中的正确组中。

我想匹配并捕获以下情况:

  1. 命名空间::tool_name::1.0.1

  2. 命名空间::工具名

  3. 工具名::1.0.1

  4. 工具名

这是我到目前为止的正则表达式:

(?:(?P<namespace>^[^:]+)::)?(?P<name>[^:]*)(?:::(?P<version>[0-9\.]+))?

这个正则表达式适用于我所有的 4 个测试用例,但我遇到的问题是在案例 3 中,tool_name 是在命名空间组中捕获的,而 1.0.1 是在名称组中捕获的。我希望它们分别被捕获在正确的组、名称和版本中

谢谢

标签: pythonregex

解决方案


*您可以通过替换为+(它看起来总是存在)来使 tool_name 正则表达式成为强制性部分,并限制此模式匹配三个点分隔的数字块与负前瞻:

^(?:(?P<namespace>[^:]+)::)?(?!\d+(?:\.\d+){2})(?P<name>[^:]+)(?:::(?P<version>\d+(?:\.\d+){2}))?

查看正则表达式演示

细节

  • ^- 字符串的开始
  • (?:(?P<namespace>[^:]+)::)?- 一个可选的非捕获组,匹配除:组“命名空间”之外的任何 1+ 字符,然后仅匹配::
  • (?!\d+(?:\.\d+){2})- 不允许digits.digits.digits模式出现在当前位置之后的负前瞻
  • (?P<name>[^:]+)- 组“名称”:任何 1 个或多个字符,除了:
  • (?:::(?P<version>\d+(?:\.\d+){2}))?- 一个可选的非捕获组匹配::,然后组“版本”捕获 1+ 个数字和 2 个重复.和 1+ 个数字。

推荐阅读