Combine Regexp?
RegexRegex Problem Overview
After collecting user input for various conditions like
- Starts with :
/(^@)/
- Ends with :
/(@$)/
- Contains :
/@/
- Doesn't contains
To make single regex if user enter multiple conditions,
I combine them with "|"
so if 1 and 2 given it become /(^@)|(@$)/
This method works so far but,
I'm not able to determine correctly, What should be the regex for the 4th condition? And combining regex this way work?
> Update: @(user input) won't be same > for two conditions and not all four > conditions always present but they can > be and in future I might need more > conditions like "is exactly" and "is > exactly not" etc. so, I'm more curious > to know this approach will scale ? > > Also there may be issues of user input > cleanup so regex escaped properly, but > that is ignored right now.
Regex Solutions
Solution 1 - Regex
Will the conditions be ORed or ANDed together?
Starts with: abc Ends with: xyz Contains: 123 Doesn't contain: 456The OR version is fairly simple; as you said, it's mostly a matter of inserting pipes between individual conditions. The regex simply stops looking for a match as soon as one of the alternatives matches.
/^abc|xyz$|123|^(?:(?!456).)*$/
That fourth alternative may look bizarre, but that's how you express "doesn't contain" in a regex. By the way, the order of the alternatives doesn't matter; this is effectively the same regex:
/xyz$|^(?:(?!456).)*$|123|^abc/
The AND version is more complicated. After each individual regex matches, the match position has to be reset to zero so the next regex has access to the whole input. That means all of the conditions have to be expressed as lookaheads (technically, one of them doesn't have to be a lookahead, I think it expresses the intent more clearly this way). A final .*$
consummates the match.
/^(?=^abc)(?=.*xyz$)(?=.*123)(?=^(?:(?!456).)*$).*$/
And then there's the possibility of combined AND and OR conditions--that's where the real fun starts. :D
Solution 2 - Regex
Doesn't contain @: /(^[^@]*$)/
Combining works if the intended result of combination is that any of them matching results in the whole regexp matching.
Solution 3 - Regex
If a string must not contain @
, every character must be another character than @
:
/^[^@]*$/
This will match any string of any length that does not contain @
.
Another possible solution would be to invert the boolean result of /@/
.
Solution 4 - Regex
In my experience with regex you really need to focus on what EXACTLY you are trying to match, rather than what NOT to match.
for example
\d{2}
[1-9][0-9]
The first expression will match any 2 digits....and the second will match 1 digit from 1 to 9 and 1 digit - any digit. So if you type 07 the first expression will validate it, but the second one will not.
See this for advanced reference:
http://www.regular-expressions.info/refadv.html
EDITED:
^((?!my string).)*$
Is the regular expression for does not contain "my string".
Solution 5 - Regex
1 + 2 + 4 conditions: starts|ends, but not in the middle
/^@[^@]*@?$|^@?[^@]*@$/
is almost the same that:
/^@?[^@]*@?$/
but this one matches any string without @, sample 'my name is hal9000'
Solution 6 - Regex
Combining the regex for the fourth option with any of the others doesn't work within one regex. 4 + 1 would mean either the string starts with @ or doesn't contain @ at all. You're going to need two separate comparisons to do that.