Qiao
Qiao

Reputation: 17049

Regex match word with optional length

I need to match word as fully as possible. There is minimum "base", and then everything else is optional. For example, word "running" with base "run" should match longest among "run, runn, runni, runnin, running"

I came up with this solution: /run(?:ning|nin|ni|n)?/, it works, but it is not pretty.

/run[ning]*/ also works, it is pretty but it is fuzzy, can have errors (runnnnning).

Is it possible to use conditions: if "run" is followed by "n", select it, if this "n" followed by "i" select it ... ?

Upvotes: 1

Views: 98

Answers (1)

Tom Lord
Tom Lord

Reputation: 28285

To be honest, I think your existing solution is OK; I doubt you'll find a way to make it much clearer. The only real alternative approach I can suggest would be to write this as:

/run(?:n(?:n(?:i(?:n(?:g)?)?)?)?)?/

...But that's much more confusing in my opinion!

However, you could instead focus on writing a helper method to abstract this complexity away. For example:

def partial_word_regex(word, min_length)
  # e.g. ["ning", "ing", "ng", "g", ""]
  extensions = 0.upto(word.length - min_length).map { |n| word[min_length..-n-1] }

  # e.g. /run(?:ning|nin|ni|n|)/
  /#{word[0..min_length-1]}(?:#{extensions.join('|')})/
end

# Usage:
partial_word_regex("running", 3)

Upvotes: 1

Related Questions