258
votes

I'm currently programming a vocabulary algorithm that checks if a user has typed in the word correctly. I have the following situation: The correct solution for the word would be "part1, part2". The user should be able to enter either "part1" (answer 1), "part2" (answer 2) or "part1, part2" (answer 3). I now try to match the string given by the user with the following, automatically created, regex expression:

^(part1|part2)$

This only returns answer 1 and 2 as correct while answer 3 would be wrong. I'm now wondering whether there's an operator similar to | that says and/or instead of either...or.

May anyone help me solve this problem?

6
Regular expressions might not be the best solution for this. I'd use normal string methods.Felix Kling
This problem is poorly specified. Why are you using pattern matching when all you need is an exact string comparison against a set of legal strings? Unless your regex compiler optimizes alternatives into an O(1) trie structure the way Perl’s does, you should probably be doing a test against hash membership instead. Other regex engines just aren’t very clever at this.tchrist
@tchrist The use case could be a mongodb $or regex matchNadir Abbas

6 Answers

324
votes

I'm going to assume you want to build a the regex dynamically to contain other words than part1 and part2, and that you want order not to matter. If so you can use something like this:

((^|, )(part1|part2|part3))+$

Positive matches:

part1
part2, part1
part1, part2, part3

Negative matches:

part1,           //with and without trailing spaces.
part3, part2, 
otherpart1
37
votes
'^(part1|part2|part1,part2)$'

does it work?

5
votes

Does this work without alternation?

^((part)1(, \22)?)?(part2)?$

or why not this?

^((part)1(, (\22))?)?(\4)?$

The first works for all conditions the second for all but part2(using GNU sed 4.1.5)

4
votes

Not an expert in regex, but you can do ^((part1|part2)|(part1, part2))$. In words: "part 1 or part2 or both"

2
votes

Or you can use this:

^(?:part[12]|(part)1,\12)$
1
votes

use
if in vim:

:s/{\|}/"/g

will replace { and } on " so {lol} becomes "lol"