Manthan Jamdagni
Manthan Jamdagni

Reputation: 1031

Regex not completely matching the desired patterns

I've been trying to write a regex to stictly match the following patterns - 3+, 3 months +, 3+ months, 3m+, 3 years +, 3y+, 3+ years. I've written a pattern - [0-9]{1,2}\s?(m|months?|y|years?)?\s?\+ which works for most of the cases exept the 3+ months & 3+ years here it matches just the 3+ part and not the month part. I want to use the matched string somewhere and this causes an issue. To accomodate this I tried adding another group to make the regex look like [0-9]{1,2}\s?(m|months?|y|years?)?\s?\+ (m|months?|y|years?)\s|$ but this is also matching for 6+ math. Can someone help me with what the issue is here, also can this regex be improved?

I can use multiple regex to solve different different use cases, but I wanted to achieve this using only 1 regex.

Thanks

Upvotes: 0

Views: 50

Answers (3)

JohnJeanJuan
JohnJeanJuan

Reputation: 48

UPDATED:

I overlooked the strictness requirement. Something that helps me figuring out these problems is breaking the pattern down in a logic tree of sorts, like so:

  1. Only XX months allowed
  2. Only XX years allowed - \d{1,2}
  3. If ## followed by a +
    • It must be followed by \s*(months|years)
  4. If ## followed by a [my]
    • It must be followed by \s*\+
  5. Close it off with $

That gets us on the right track to what we want. Again, it still permits undesired cases, but just revisit that thought exercise, tinker with the conditionals, and try to find common components that restrict the full regex to neat grouping of stricter patterns.

This should be closer to the strict solution you’re looking for:

\d{1,2}\s*([my]?\+|\+?\s*(months|years)|(months|years)\s*\+?)\s*$

===========================

ORIGINAL POST:

Here’s a first pass at a condensed version of what you want: \d{1,2}[\+my]?\s*(months|years)?\s*\+?

Here’s a breakdown of the approach I took:

(\d{1,2})

^ Accommodate any two numbers (your approach is fine, \d means any number 0-9, saves a few characters)

([\+my]?\s*)

^ The characters following the given number may be m, y, or + followed by any number of spaces.

(months|years)?

^ We’ve accounted for all spaces with the previous piece of regex, so lets just say there might be months|years at this point.

(\s*\+?)

^ Last potential symbol is a +, but it might have several spaces in front of it.

Upvotes: 2

anubhava
anubhava

Reputation: 785196

You may use this regex with optional matches:

\d{1,2}\+?(?:\s?(?:months?|years?|[my])\b\s?\+?)?

RegEx Demo

Upvotes: 0

Vlam
Vlam

Reputation: 1798

Try the following regex

((?:\d{1,2}\+ (?:months|years))|(?:\d{1,2}\+)|(?:\d{1,2} (?:months|years) \+)|(?:\d{1,2}(?:m|y)\+))

Upvotes: 0

Related Questions