具有正后视的复杂 (PHP) 正则表达式

Complex (PHP) regex with positive lookbehind

我想匹配以下测试字符串(第 2 行第 3 行),其中 第 3 行 将是随机顺序,第 2 行 将是一个常数。

    X509v3 extensions:
        X509v3 Subject Alternative Name:
            IP Address:55.66.77.88, DNS:example.com, DNS:www.example.com, IP Address:44.33.22.11
Signature Algorithm: sha384WithRSAEncryption

我可以使用以下正则表达式在第 3 行找到匹配项:

\s+(?|(DNS):([\w\.\d]+),|(IP Address):([\d\.]+))

但是,当我添加正向后视时,如下所示,我不再获得完全匹配。 任何帮助将不胜感激。

(?<=X509v3 Subject Alternative Name:\s)\s+(?|(DNS):([\w\.\d]+),|(IP Address):([\d\.]+))

当我们添加正向后视时,只有下一行中的第一个条目会匹配,因为对于其余的 IP 地址或 DNS 名称,正向后向并不真正在它们之前。文本 X509v3 Subject Alternative Name: 仅在第一个 IP 地址或 DNS 名称之前。

这是后视模式(模式 1):

(?<=X509v3 Subject Alternative Name:)\s+(DNS:([\w\.\d]+),|IP Address:([\d\.]+))

这是 IP 地址或 DNS 名称模式 (模式 2):

\s+(DNS:([\w\.\d]+),|IP Address:([\d\.]+))

因此,我认为你必须这样做:

  1. 首先检查文本是否与模式 1 匹配。这将确保您选择了所需的行或条目。
  2. 接下来,应用模式 2 并选择值。

我在 Java 上对其进行了测试,发现它可以正常工作。由于您在标题中提到了PHP,我认为该代码可能对您没有用。因此,不发布。

由于您正在提取,因此您可以将您的模式大大简化为 (DNS|IP Address):([\w.]+),其中 IP 地址与 [\w.]+ 匹配,与 DNS 相同,因为 \w 也匹配数字。然后,要定义自定义边界,您可以使用基于 \G 的模式,例如

(?:\G(?!\A),\s*|X509v3 Subject Alternative Name:\s+)(DNS|IP Address):([\w.]+)

regex demo

详情

  • (?:\G(?!\A),\s*|X509v3 Subject Alternative Name:\s+) - 两种选择之一:
    • \G(?!\A),\s* - 上一个成功匹配的结尾 (\G(?!\A)) 然后是一个逗号和 0+ 个空格
    • | - 或
    • X509v3 Subject Alternative Name:\s+ - X509v3 Subject Alternative Name: 子字符串,然后是 1+ 个空格
  • (DNS|IP Address) - 第 1 组:DNSIP Address
  • : - 冒号
  • ([\w.]+) - 第 2 组:一个或多个单词(字母、数字或 _)或点字符。