正则表达式匹配返回几个捕获块

问题描述

我想从某些文本中提取经验。它可能包含几年和几个月的变化。我试图使用正则表达式制作两个非捕获块,但最终给了我几个捕获实例。

工作经验:15年2个月

正则表达式为:

((?:\d{1,3}(?:\.)?(?:\d{1})?\s+year(?:s)?\s+)?(?:\d{1,3}\s+month(?:s)?)?)

尽管它捕获了我要查找的字符串,但它也返回了虚假匹配项。

一种简单地加入所有实例的方法,因为其余匹配项为'',但这对编码实践而言并不公平。

我需要一点帮助才能弄清楚哪里出了问题?

道歉, 我错过了导致所有人偏离轨道的一种情况。有一些像

的字符串
2 Months
1 year 3 months
1.5 year
15 year 2 months

谢谢。

解决方法

您可以按以下方式减少正则表达式以仅捕获所需的那些组。这里\1将具有必需的字符串。
这也将匹配用制表符和换行符分隔的字符串。

^\D*((?:[\d.]+\s*[yY]ears?)?\s*(?:[\d.]+\s*[mM]onths?)?)

Demo

,

该模式也匹配每个字符之前和之后的位置,因为该模式中的所有部分都是可选的。

您可以像(?:s)?一样写s?之类的内容,也可以省略{1}


如果您不想匹配空字符串,则可以匹配可选的年份部分,然后匹配月份,或者匹配月份部分。

您可以使用不区分大小写的匹配,也可以使用字符类[yY]来匹配小写字符和大写字符

只需要匹配,就可以省略捕获组。

\b(?:\d+(?:\.\d+)? years? )?\d{1,3} months?\b|\b\d+(?:\.\d+)? years?\b

说明

  • \b(?:\d+(?:\.\d+)? years? )?将可选的年份部分与可选的小数部分匹配
  • \d{1,3} months?\b将月份部分与1-3位数字匹配
  • |
  • \b\d+(?:\.\d+)? years?\b匹配年份部分

Regex demo

请注意\s也可以匹配换行符