0

I'm trying to match (along with capture groups) the following input:

favorite colors are red orange yellow
favorite colors are red orange

The first phrase has 3 colors, the second phrase has 2 colors.

My regex is:

/favorite colors are (.*) (.*) (.*)/i

However, this regex only works if I have 3 colors. How could I rewrite this regex so that it can also accept 2 colors? I've tried adding a ? to the end of the 3 capture group but that requires that my input phrase to have a trailing space.

I don't mind having the 3 color be empty in the capture group if the 3rd color isn't supplied.

As per the http://stackoverflow.com/questions/12451731 post, the suggested fix as /favorite colors are (.*) (.*)(?: (.*))?/i, however, it does not work because it matches red orange as group 1, and yellow as group 2, while red should be in group 1, orange should be in group 2 and yellow should be in group 3. The http://stackoverflow.com/questions/8991178 post suggests using [^\s], but it turns out that matches trailing dots.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Kevin
  • 3,441
  • 6
  • 34
  • 40
  • You might want to ensure that the captured groups only accept single words, rather than `(.*)` – CertainPerformance Jul 11 '18 at 21:28
  • Hi, please take a look at duplicate topic and if it didn't give you some insights, edit your question accordingly. – revo Jul 11 '18 at 21:34
  • @revo It is not a dupe of [that question](https://stackoverflow.com/questions/12451731/how-do-i-make-part-of-a-regex-match-optional), since it is not *just* about making a part of a regex optional. See [`favorite colors are (.*) (.*)(?: (.*))?`](https://regex101.com/r/eGTfHV/1), it does not work. – Wiktor Stribiżew Jul 11 '18 at 21:35
  • I added another dupe for it. – revo Jul 12 '18 at 06:32

1 Answers1

0

The favorite colors are (.*) (.*) (.*) pattern requires at least one space between Group 1 and Group 2, and between Group 2 and Group 3.

Besides, to match just word chars, you need to use \w instead of the . that matches any char but a line break char.

You may use an optional non-capturing group with \w+ or \w+ patterns replacing .* ones:

/favorite colors are (\w+) (\w+)(?: (\w+))?/i

See this regex demo.

Here, (?: (\w+))? matches an optional sequence of patterns, a space and 1+ word chars (letters, digits or _) captured into Group 3.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563