我有一些输入文本,如下所示:
Oracle SQL 19c
Microsoft SQL Server 2008 R2
Microsoft SQL Server 2016
MySQL 8.2
这个正则表达式:
(^.*\s)+(\d+\.?\d+\s?)?(.*)?
正则表达式适用于上面列表中的所有短语。 例如:
Group 1: Microsoft SQL Server
Group 2: 2012
Group 3: ""
但是,
Microsoft SQL Server 2008 R2
并没有像我预期的那样工作:
这个短语,分组为:
Match 1: Microsoft SQL Server 2008 R2
Group 1: Microsoft SQL Server 2008
Group 3: R2
我不明白为什么没有显示第 2 组!我的正则表达式有什么问题?
我在评论中提供的建议是基于这样的假设:您的字符串始终包含一个数字,可能后跟一个可选的句点+更多数字,前面总是有一个空格。正则表达式的问题在于它的所有部分都是可选的,因此第一个
.*
会抓取它能抓取的所有文本,并且由于 \s
之后有一个强制性的 .*
,它注定会匹配到最后一个空格和其余部分与最后一个贪婪的 .*
匹配(在 ?
之后添加 (.*)
不会使其变得懒惰)。
所以,建议的模式看起来像
^(.*?)\s+(\d+(?:\.\d+)?)\s*(.*)
它是这样匹配的:
^
- 字符串的开头(.*?)
- 第 1 组:除换行符之外的任何零个或多个字符尽可能少(惰性点模式)\s+
- 一个或多个空格(\d+(?:\.\d+)?)
- 第 2 组:一位或多位数字,然后是 .
和一位或多位数字的可选序列(请注意,\d+\.?\d+
要求存在至少 2 个连续数字!)\s*
- 零个或多个空格(.*)
- 第 3 组:除换行符之外的尽可能多的任何零个或多个字符(贪婪点模式)。请参阅 regex 演示(
\s
被替换为空格,因为演示模式是针对多行而不是单个多行字符串运行)。