如何调整此正则表达式以不知道键值对的顺序

How to adapt this regex to be agnostic of the order of the key-value pairs

我构建了这个正则表达式来从自动生成的锁定文件中提取包的版本号:

\[\[package\]\]\s(?:[a-z-]+ = \"?.*\"?\s)*name = \"NAME\"\s(?:[a-z-]+ = \"?.*\"?\s)*version = \"([ab0-9.]+)\"

主题文件看起来像这样(缩短了,有很多这样的块):

[[package]]
category = "main"
description = "Some. , - description"
name = "django"
optional = false
python-versions = ">=3.5"
version = "2.2.17"

[package.dependencies]
django = ">=1.8.0"
redis = ">=3"
rq = ">=0.13,<1.0"

[package.extras]
Sentry = ["raven (>=6.1.0)"]
testing = ["mock (>=2.0.0)"]

这似乎很有效。问题是有时,两个重要键的顺序可能不同,例如:

[[package]]
category = "main"
description = "Some. , - description"
version = "2.2.17"
optional = false
name = "django"
python-versions = ">=3.5"

这将导致此正则表达式失败。

我想找到一个块(以 [[package]] 开始并以换行符结束,包含字符串 ^name = \"NAME\",并且 在该块内 , 请务必找到 version 键的值,无论它们的顺序如何。

我已经阅读了一些关于 lookaheads/lookbehinds 的资料,但我无法将其应用到此。

您可以使用先行断言来匹配主正则表达式中的包名称和捕获版本:

\[\[package]]\s(?=(?:[a-z-]+ = "?[^"]*"?\s)*?name = "django"\s)(?:[a-z-]+ = "?[^"]*"?\s)*?version = "([ab0-9.]+)"

RegEx Demo

正则表达式详细信息:

  • \[\[package]]\s:匹配 [[package]] 后跟空格
  • (?=(?:[a-z-]+ = "?[^"]*"?\s)*?name = "django"\s):肯定的前瞻性断言我们在这个包中的某处有一个 属性 name = "django"
  • (?:[a-z-]+ = "?[^"]*"?\s)*?:匹配0个或更多属性行
  • version = "([ab0-9.]+)": 匹配version 属性和捕获组#1
  • 中的捕获版本号