preg_match_all 没有完成字符串匹配

preg_match_all not completing the string match

我想在大海捞针中匹配所有 needle 实例。我的针是:

/([0-9]{6,}) ([0-9]{10,}) ([0-9]{4,5}) (.{5,}) ([0-9]{1,}) ([0-9\.,]{4,8}) ([0-9\.,]{4,8})/gU

我的干草堆是:

6292181 5702016627428 2304 WIDGET 18 14.12 254.16 6102211 5702015357180 10696 WIDGET 16 32.34 517.44 6332205 5702016911053 10946 WIDGET 6 32.36 194.16 

我遇到的问题是没有包括每场比赛结束时的小数位。所以不是匹配

 6292181 5702016627428 2304 WIDGET 18 14.12 254.16 
 6102211 5702015357180 10696 WIDGET 16 32.34 517.44
 6332205 5702016911053 10946 WIDGET 6 32.36 194.16 

匹配为

 6292181 5702016627428 2304 WIDGET 18 14.12 254 
 6102211 5702015357180 10696 WIDGET 16 32.34 517
 6332205 5702016911053 10946 WIDGET 6 32.36 194 

在我看来 gU 参数有问题。

这是我的工作:https://regex101.com/r/OgKqOV/1

在最后一部分添加 + 会有所帮助。它将模式从懒惰转换为主动。

因此正则表达式变为:

([0-9]{6,}) ([0-9]{10,}) ([0-9]{4,5}) (.{5,}) ([0-9]{1,}) ([0-9\.,]{4,8}) ([0-9\.,]{4,8}+)

工作示例(与您的相同):

https://regex101.com/r/h5gbjL/1

U 修饰符将所有贪婪量词转换为惰性量词,将所有惰性量词转换为贪婪量词。如果你想让模式更短,当这个模式包含比贪婪量词更多的懒惰量词时,它才“有用”,因为你要输入的问号更少。 (IMO,它永远没有用)。

大多数时候人们把它当作魔杖,用它来解决他们所有的问题,而不是花 10 分钟来理解量词的工作原理。

所以,要解决你的问题,你所要做的就是删除这个无用的 U 并使这个带有问号的量词变得惰性:(.{5,}?)。 所有其他量词都必须是贪心的,因为它们被以下 space 停止(不在字符 class [0-9] 中),因此您不需要更改它们。

([0-9]{6,}) ([0-9]{10,}) ([0-9]{4,5}) (.{5,}?) ([0-9]+) ([0-9.,]{4,8}) ([0-9.,]{4,8})

demo

您可以在字符 class.

中使用 \d 而不是 [0-9]0-9 来缩短您的模式
(\d{6,}) (\d{10,}) (\d{4,5}) (.{5,}?) (\d+) ([\d.,]{4,8}) ([\d.,]{4,8})

如果您想确保匹配前后没有连续的数字,您可以在模式的开头和结尾添加单词边界:

\b(\d{6,}) (\d{10,}) (\d{4,5}) (.{5,}?) (\d+) ([\d.,]{4,8}) ([\d.,]{4,8})\b