匹配最短的 "lol" 可能:`'looool lool lol loool'.match(/(lo+?l)/)[1] // => 'looool'`?

Match the shortest "lol" possible: `'looool lool lol loool'.match(/(lo+?l)/)[1] // => 'looool'`?

上面的例子returns与"leftmost longest"匹配。同样,这个例子 returns 最右边的匹配:

'looool lool lol loool'.match(/.*(lo+?l)/)[1]
// => 'loool'

但我很好奇可以匹配最短 "lol" 的解决方案。

没有正则表达式元量词可以让您请求最短的整体匹配。 "Leftmost" 胜过长度考虑,无论是否贪婪:

'lol looool lool lol loool'.match(/(lo+l)/)[1] 
//=> "lol"

您可以通过使前缀部分非贪婪来修改您的 "rightmost" 版本,但这仍然无法得到您想要的:

'looool lool lol loool'.match(/.*?(lo+?l)/)[1]
//=> "looool"

'looool lool lol loool'.match(/.+?(lo+?l)/)[1]
//=> "lool"

您确实需要在正则表达式之外使用逻辑来最小化长度。在 Ruby 中,您可以这样做:

'looool lool lol loool'.scan(/lo+l/).min_by(&:length) 
# => "lol"

Javascript让你更努力一点:

'looool lool lol loool'.match(/lo+l/g).reduce(
  function(shortest, next) { 
    return (!shortest || (next.length < shortest.length))  ? next : shortest; 
  });
//=> "lol"

但是无论您的目标语言是什么,您都可能需要使用相同的基本思想。