在正则匹配中分离匹配组

3

我正在编写一个正则表达式,用于返回安装在 Windows 机器上的 OpenSSH 版本号,以供我们的监控系统使用。我有以下两个字符串:

version=OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.4
version=OpenSSH_7.1p1 Microsoft_Win32_port_with_VS Dec 22 2015, OpenSSL 1.0.2d 9 Jul 2015

当正则表达式为:
\S+Windows_(\d.\d)

那么7.7就在第一组,监控系统可以看到它。但是当我试图覆盖7.1字符串时,分组就会混乱。

(\S+Windows_(\d.\d)|\S+OpenSSH_(\d.\d))

我该如何修改这个字符串以分离第三组和第一组(分别为7.1和7.7)?

谢谢。

4个回答

2

您可以考虑完全更改正则表达式,这样您只需要一个捕获组。

您正在尝试捕获的两个数字都以version=OpenSSH_开头,中间有一些可选字符。

因此,您可以这样做:

version=OpenSSH_\D*(\d\.\d)

无论哪种情况下都能捕获正确的版本。优点是您不需要知道使用哪个匹配组--返回的始终是第1组。

演示

如果您想使用您已经拥有的可选形式,也可以重构一下,只使用一个捕获组:

(?:Windows_|\S+OpenSSH_)(\d.\d)

演示

请注意,这种格式将会有更多的回溯,并且可能比第一个形式低效10倍。


0
使用非捕获组:
(?:\S+Windows_(\d\.\d)|\S+OpenSSH_(\d\.\d))

试一下。


你应该转义 . 才能获取一个字面上的 .,否则 \d.\d 将与两个数字之间的任何字符匹配。 - dawg
糟糕!谢谢。必须停下来,不要匆忙。 - Aankhen

0
(?:(\S+Windows_)|(\S+OpenSSH_))(\d+\.\d+)

你可以像这样分组,这样它总是在同一组中(在group3中),(?:)是一个非捕获组。 https://regex101.com/r/ZgtiYo/3

0

正如您所看到的,这个问题有更多的解决方案。您尝试的正则表达式中有一个有趣的地方,就是在集合内创建了比需要更多的捕获组。有一种特定的结构可以用来解决这个问题(如果支持):分支重置组

本质上,分支重置组内的捕获组在所有选项之间共享,可以将其视为一种高级回溯,其中组被重复使用。

这是新的正则表达式:

((?|\S+OpenSSH_(\d\.\d)|\S+Windows_(\d\.\d)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接