RegExp: How to find only one match (or not match pattern)

Viewed 82

I can't get how to write regexp right to be able match only heo. So for example if we found some l char during parsing - cancel that match then.

'heo heo helo'.match(/he.*(?!l)o/gi) // should be only [heo, heo]

UPD: I need to match as mutch as possible times among the string. Not the first one. Thanks

Example (wrong one):

console.log('heo heo helo'.match(/he.*(?!l)o/gi))

2 Answers

There are two issues:

  • .* - matches any zero or more chars other than line break chars as many as possible, and thus will match till the last occurrence of the subsequent patterns in the regex. You might use a non-greedy .*? here to fix the issue.
  • (?!l)o - always matches o, since o is not l, (?!l), a negative lookahead, always returns true, saying, yes, go ahead and return the match. You wanted a negative lookbehind, (?<!l) here.

To match strings starting with he and then matching any chars (other than line break chars) as few as possible and then o not preceded with l, you can use

/he.*?(?<!l)o/gi

See this regex demo. The .*?(?<!l)o pattern matches any 0+ chars other than line break chars as few as possible up to the leftmot o that is not immediately preceded with l.

Now, if you just want to match words that start with he and end with o not preceded with l, you can use

/\bhe[a-z]*(?<!l)o\b/gi
/\bhe(?![a-z]*lo\b)[a-z]*o\b/gi

See this regex demo and this regex demo.

console.log('heo heo helo'.match(/he.*(?!l)o/gi))

You matches any characters .* before checking the condition (?!l). Your regex should check condition before matching characters.

Besides, you want to match only hexxxo (x is not l), so you should use \b in your regex. I suggest following regex.

console.log('heo heo helo aheob'.match(/\bhe[^l]*o\b/gi));

Related