There are many variations on this type of question, but none that I could see match exactly what I need - apologies if I've missed a different answer.
As part of a unit test, I want to test whether a given string will match a regex pattern. The string will usually take a comma-separated form using the same set of substrings in the same order:
accounts,leads,contacts,opportunities
However, sometimes some of the substrings might not be present. For example, the string might be:
accounts,contacts
Or:
leads,opportunities
The string could also be empty.
What I want is a regex pattern that will always match variations on this string and confirm that there are no trailing or leading commas around it. So far I have:
"^[^,]?(accounts,?)?(leads,?)?(contacts,?)?(opportunities)?[^,]?$".toRegex()
But this doesn't work, as the regex will still accept one trailing space or comma, or letters other than commas around it. I'm not great at Regex, so any help is appreciated.
Examples of what needs to match:
accounts,leads,contacts,opportunities // match
<emptystring> // match
accounts,opportunities // match, substrings are in correct order
leads,opportunities // match, substrings are in correct order
leads,accounts,contacts // no match, wrong order of substrings
accounts,leads,contacts, // no match, trailing comma
,accounts,leads,contacts // no match, leading comma
apples,bananas,contacts // no match, invalid substrings
CodePudding user response:
You need to use
^(?:accounts)?(?:(?:,|^)leads)?(?:(?:,|^)contacts)?(?:(?:,|^)opportunities)?$
See the regex demo. This is basically a chain of optional groups in a specified order:
^
- start of a string(?:accounts)?
- optionalaccounts
string(?:(?:,|^)leads)?
- an optional,
or start of string and thenleads
string(?:(?:,|^)contacts)?
- an optional,
or start of string and then acontacts
string(?:(?:,|^)opportunities)?
- an optional,
or start of string and then anopportunities
string$
- end of string.