-2

The above example returns the "leftmost longest" match. Likewise, this example returns the rightmost match:

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

But i'm curious of a solution to match the shortest "lol" possible.

Nieralyte
  • 444
  • 1
  • 5
  • 11
  • 2
    You haven't specified a language for the regular expression to know which dialect you're referring to. – zzzzBov Aug 26 '15 at 15:14
  • 1
    Regex is powerful to find patterns, not size. Depending on the language you're using, the solution can vary. – Maroun Aug 26 '15 at 15:14
  • 2
    You can't use regex alone to solve this problem. What you can do is iterate over all matches for the regex `lo+l` and look for the one with the shortest length. – C0deH4cker Aug 26 '15 at 15:17
  • 1
    I can think of a solution, but it requires some regex functionality which is probably pretty rare (at least in my experience) (a subpattern reference in variable length negative lookbehind and lookahead), but combining regex with basic functionality from whichever language you're using is probably a better solution anyway. Posting said solution presumably won't help you if the language you're using doesn't support it. – Bernhard Barker Aug 26 '15 at 15:18
  • 2
    For everyone saying it's *impossible* with regex... hold on a little. Maybe with javascript regex, but don't generalize like that. It is definitely possible, but I do agree it's better to use the tools in whatever language you have to do simple checks instead. – ndnenkov Aug 26 '15 at 15:27

1 Answers1

4

There isn't a regex metaquantifier that lets you ask for the shortest match overall. "Leftmost" trumps length considerations, whether greedy or not:

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

You can modify your "rightmost" version by making the prefix part non-greedy, but that still doesn't get what you want:

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

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

You really need to use logic outside of the regex to minimize the length. In Ruby, you can do this:

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

Javascript makes you work a little harder:

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

But the same basic idea is likely what you'll need to do whatever your target language is.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175