带有可选捕获组的正则表达式

regex with optional capture group

我正在尝试使用正则表达式从字符串中获取数量、单位和物质。单位和物质来自预定义的列表。

所以:

我可以使用以下正则表达式实现此目的: (\d*) ?(kg|ml|gallon).*(water|oil)

问题是我不知道如何使最后一个捕获组可选。如果物质不在预定义的列表中,我仍然想获得数量和单位。所以:

我已尝试将最后一组包装在一个可选的非捕获组中,如此处所述: 但没有成功。

这是在线正则表达式测试器中的当前正则表达式:https://regex101.com/r/hV3wQ3/55

您正在尝试使用 (\d+) ?(kg|ml|gallon).*(?:(water|oil))?,但此模式无法捕获 water / oil。问题是 .* 抓取除换行符以外的任何 0+ 个字符,直到字符串/行的末尾,当正则表达式索引存在时,在字符串末尾尝试 (?:(water|oil))? 。由于(?:(water|oil))?可以匹配空字符串,所以它匹配字符串末尾的位置,并返回匹配。

您仍然可以强制使用捕获组,但将 .* 和捕获组包裹在一个可选的 non-capturing 组中:

(\d+) ?(kg|ml|gallon)(?:.*(water|oil))?
                     ^^^             ^^ 

regex demo

(?:.*(water|oil))? 匹配 1 次或 0 次(贪婪地)出现除换行符以外的任何 0+ 字符(.*),然后是 wateroil .