Reputation: 1541
This is probably as basic as this gets, but it's the first time I've seen regular expressions and everyone else in the class apparently took another class on it already. The main thing I'm not following is using the carot (supposed to allow everything except for what's after it).
So the problem is:
Give a regular expression for: All Strings over {0,1,2} that does not include the substring 12.
I know (0|1|2)* would be all strings. However, you'd want to avoid 12. The way I'm looking at this is that you just don't want a 2 after a 1, so I put:
(0|1[^2]|2)*
The way I read this is, if it's a 0, put 0 and do the parenthesis again; if it's a 1, put a 1 and SOMETHING that isn't a 2. However, technically "nothing" is something, so would it come back around and be like 1[nothing], circle around and put 2, thus making it 1[nothing]2 = 12? Or would it do as I'd hope and make sure a 2 would never come after a 1, while still letting the process continue?
I'm not entirely sure if what I said makes sense, so just let me know if you need clarification and I'll try hehe
Thanks in advance.
Sean
Upvotes: 1
Views: 2201
Reputation: 592
I admit, I based my answer on Bergi's, but mine will not accept 112 (or 1112, or 11112, etc).
(0|1+[^12]|2)*1*
I tested this regex here: http://regexhero.net/tester/
Hope you see this before you turn it in tomorrow...
EDIT: In order to test it properly, please use the ^ and $ anchors that Pettit mentioned. However, do not include them when you turn the homework in.
Upvotes: 0
Reputation: 664297
The main thing I'm not following is using the carot (supposed to allow everything except for what's after it).
I guess you mean the caret? Have a look at negated character classes.
[…] put a 1 and SOMETHING that isn't a 2. However, technically "nothing" is something, so would it come back around and be like 1[nothing], circle around and put 2, thus making it 1[nothing]2 = 12?
No. A character class does always match exactly one character, it cannot match nothing. The expression [^2]
is not meant as "anything - including nothing - that is not a 2
", but specifically "one thing that is not a 2
". One could however make it optional explicitly.
Or would it do as I'd hope and make sure a 2 would never come after a 1, while still letting the process continue?
Yes. However, it does always require at least one character after the 1
, so a string that ends in 1
would be invalid as well. You should allow 1
s in the end explicitly:
(0|1[^2]|2)*1*
Upvotes: 1
Reputation: 141
Your regex will process characters from the input string one at a time. Your regex will match the string "112", which doesn't meet your requirements. (The first "1" will match the 1 in your pattern, and then the second "1" will match [^2], because "1" isn't a 2. Then it'll match the "2" in the string against the 2 in the pattern.
You need a way to say "a 1 that isn't followed by a 2" while not actually "consuming" the character after the 1. Here's a regex that does that, but it requires negative look-ahead:
^(?:0|1(?!2)|2)*$
This says that the entire string (that's why I use the ^ and $ anchors) must consist of characters from the parenthesized expression: either a "0", a "2", or a "1" that isn't immediately followed by a "2".
Upvotes: 2