"Write a regular expression that describes all strings of zeroes and ones representing binary numbers that are either odd or divisible by 8. The numbers may not have any leading zeros."
I gave my answer as (000|1)$ which was marked wrong. I cannot see the reason why. Please explain! Thanks in advance.
You forgot two of the requirements.
It must contain only 1s and 0s:
^[01]*(000|1)$
There may be no leading 0s:
^(?!0)[01]*(000|1)$
If lookaheads are not allowed, it becomes a bit trickier:
^1[01]*(000|1)$|^1$
Another addition, if you are allowed to use only the regular expression constructs that are available in "theoretical" regular expressions (alternation, group and repetition), it would look like this (anchors are implicit in this case):
1(0|1)*(000|1)|1
Related
I have this following questing in regular expression and I just can't get my head around these kind of problems.
L1 = { 0n1m | n≥3 ∧ m is odd }
How would I write a regular expression for this sort of problem when the alphabet is {0,1}.
What's the answer?
The regular expression for your example is:
000+1(11)*1
So what does this do?
The first two characters, 00, are literal zeros. This is going to be important for the next point
The second two characters, 0+, mean "at least one zero, no upper bound". These first four characters satisfy the first condition, which is that we have at least three zeros.
The next character, 1, is a literal one. Since we need to have an odd number of ones, this is the smallest number we're allowed to have
The last-but-one characters, (11), represent a logical grouping of two literal ones, and the ending * says to match this grouping zero or more times. Since we always have at least one 1, we'll always match an odd number. So we're done.
How'd I get that?
The key is knowing regular expression syntax. I happen to have quite a bit of experience in it, but this website helped me to verify.
Once you know the basic building blocks of regex, you need to break down your problem into what you can represent.
For example, regex allows us to specify a lower AND upper bound for matching (the {x,y} syntax), but doesn't allow to specify just a lower bound ({x} will match exactly x times). So I knew I would have to use either + or * to specify the zeros, as those are the only specifiers that permit an infinite number of matches. I also knew that it didn't make sense to apply those modifiers to a group; the restriction that we must have at least 3 zeroes doesn't imply that we must have a multiple of three, for example, so (000)+ was out. I had to apply the modifier to only one character, which meant I had to match a few literals first. 000 guarantees matching exactly three 0s, and 0* (Final expression 0000*) does exactly what I want, and then I condensed that to the equivalent 000+.
For the second condition, I had to think about what an odd number is. By definition, an odd number can be expressed by 2*k + 1, where k is an integer. So I had to match one 1 (Hence the literal 1), and some number of the substring 11. That led me to the group, and then the *. On a slightly different problem, you could write 1(11)+ to match any odd number of ones, and at least 3.
1 A colleague of mine pointed out to me that the + operator isn't technically part of the formal definition of regular expressions. If this is an academic question rather than a programming one, you might find the 0000* version more helpful. In that case, the final string would be 0000*1(11)*
Write an expression that contains an even number of 0s or an odd number of 1s
I got it down to:
1*(01*01*)* + 0*10*(10*10*)*
where the first part represents an even number of 0s and the second part an odd number of 1s
However, there's supposed to be a simplified solution that I'm not seeing. Any tips?
Odd-1s part: 0*1(0|10*1)*
Even-0s part, depends:
Empty string is correct: (1|01*0)*
No-0s is even-0s: (1|01*0)+
Must have at least two 0s: 1*(01*01*)+ (as in OP)
old answer: correct under case 1 and 2
(1*(01*0)*)+ | 0*1(0*(10*1)*)*
Kudos to #OGHaza for helpful comments.
Making use of the fact that even-length strings ALWAYS satisfy your constraints:
^(([01]{2})*|1*(01*01*)*)$
Define "shortest". If you're looking for the shortest evaluation time (i.e. fastest) then make sure you do not use capture groups.
here's an example in javascript
^(?:1*(?:01*0)*)+|0*1(?:0*(?:10*1)*)*$
which shows as 20% faster than this expression that uses capture groups but will give you the same answer
^(1*(01*0)*)+|0*1(0*(10*1)*)*$
The most simplified solution I found is:
1+0(0+1)((1+0)(1+0))*
what about this expression:
(1(11)*+(00)*)
With the fewest symbols,
1*(01*01*)*
What is the regular expression for the language 0m1n where m+n is even?
If you mean a string 000...111... where the length of the string is even, you can use ^(00)*(01)?(11)*$
Ok, so you need to consider for zero the cases when there are odd and when they are even. This requires two states, one for even zeros, one for odd zeros. Then for the odd zero case you need to have 1 one then an even number of ones. For the even case you just need an even number of ones.
Its easy to write the DFA, but I don't know how to plot it here, so I'm going to hazard a guess at the regular expression:
(0 (00)* 1 (11)*) \/ (00)*(11)*
I got the following regex that almost does the work but does not exclude zero ...How to do that?
^(\d|\d{1,9}|1\d{1,9}|20\d{8}|213\d{7}|2146\d{6}|21473\d{5}|214747\d{4}|2147482\d{3}|21474835\d{2}|214748364[0-7])$
Also can anybody explain a bit how this works?
Regular expressions are not the right tool for this job. A much better solution is to extract the integer from your string (you can use a regex for this, just \d+), then convert that to an integer, then check the integer against your desired range.
An important corollary is to never blindly use a regular expression (or any code, really) that you don't understand yourself. What would you do if you used the regular expression above, then a requirement came in to modify the acceptable range?
As Greg said, regexes are not the right tool for the job here. But if you insist on knowing how the regex you pasted works:
The most important thing to remember is that 2**31 - 1 = 2147483647 (a number with 10 digits). In essence, the regex says:
The number can have 1-9 digits, OR
It can be 1 with any 9 digits after it, OR
20 with any 8 digits after it, OR
213 with any 7 digits after it, OR
... I'm sure you see where it's going
It restricts the numbers to the range of being below 2147483647.
P.S. given such a number as a string s, in Python, you can just pose this condition:
1 <= int(s) <= 2**31 - 1
In addition to the other answers, your regex doesn't work (besides allowing 0): it incorrectly excludes numbers like 2100000000, 2147483639, and most of the numbers between those two. The solution is to replace most of the nnnn prefixes with nnn[0-n] (along with other fixes), but the real solution is to not use regular expressions.
I have a list of textual entries that a user can enter into the database and I need to validate these inputs with Regular Expressions because some of them are complex. One of the fields must have gaps in the numbers (i.e., 10, 12, 14, 16...). My question is, is there a Regex construct that would allow me to only match even or odd digit runs? I know I can pull this value out and do a division check on it, but I was hoping for a pure Regex solution to this if possible.
[Edit]
The solution I ended up using on this was an adaption of JaredPar's because in addition to needing only odd's or evens I also needed to constrain by a range (i.e., all even numbers between 10-40). Below is finished Regex.
^[123][02468]$
Odd Numbers
"^\d*[13579]$"
Even Numbers
"^\d*[02468]$"
Run of Odds with a , and potential whitespace separator
"$\s*(\d*[13579]\s*,\s*)*\d*[13579]$"
Run of Evens with a , and potential whitespace separator
"$\s*(\d*[02468]\s*,\s*)*\d*[02468]$"
The Regex is actually not too hard to design, if you take into account that an even or odd number can be tested by only looking at the last digit, which need to be even or odd too. So the Regex for odd number runs could be:
"^(\s*\d*[13579]\s*,)*(\s*\d*[13579]\s*)$"
Replace [13579] by [02468] for even numbers...
Do you mean something like:
/(\d*[02468](, *\d*[02468]))|(\d*[13579](, *\d*[13579]))/
or one of the three other possible interpretations of your question as worded?