为什么这个正则表达式使用* +(所有格)不匹配

时间:2015-03-03 10:47:02

标签: regex

我需要在

之类的字符串中获得[0-9。] *的最后一个匹配
one 1.234 three
some text 1.2321 xyz 1 5 1.234 and more text
some other text

但也需要它周围的文字 - 即使没有像第3行那样的数字

我想使用^(.*)([0-9\.]*+)(.*)$,但它只匹配第一个(。*)。

另一方面^(.*?)([0-9\.]*+)(.*?)$只匹配最后一个(。*?)。

为什么?我认为它会尽力满足所有规则吗?

我知道我可以排除0-9。从最后一个。*得到我想要的,但我想明白为什么上面的工作虽然我用* +

1 个答案:

答案 0 :(得分:3)

占有量词不保证最长的匹配,它只是阻止回溯。你的正则表达式都没有试图回溯,所以占有量量词没有效果。

使用第一个正则表达式,第一个(.*)消耗整个字符串,然后([0-9.]*+)和第二个(.*)每个都不消耗任何东西,因为没有什么可以匹配。

使用第二个正则表达式时,第一个(.*?)最初不会消耗任何东西,因为它不情愿。然后([0-9.]*+)成功地匹配了更多的东西,因为它仍然在字符串的开头,这不会以数字或句点开头。最后,最后(.*?)被迫消耗剩下的东西(整个字符串)尽管不情愿,因为它后面有锚($)。

要解决您的问题,我们需要了解您可以预期的输入类型。例如,如果您知道在之后之后将永远不会有任何数字或句点,您可以使用此代码:

^(.*?)(?:([0-9.]+)([^0-9.]*))?$

这里的关键是第二个捕获组([0-9.]+)使用+而不是*。如果字符串中没有数字或句点,则封闭组(?:([0-9.]+)([^0-9.]*))?将不匹配任何内容,并且初始(.*?)将被强制使用整个字符串。 (第二组和第三组将为空。)

如果字符串中有多个数字或句点序列,则第二组保证匹配最后一组,因为第三组([^0-9.]*)允许任何字符串剩余部分中的那些字符。

这非常弱,但这是我能用你提供的信息做的最好的。关键是,当你可以使用它们时,占有量词是很棒的,但这种情况几乎不会像你预期的那样频繁发生。