Regular Expression to match only odd or even number - regex

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?

Related

Regex to check if input (alphanumeric) contains a number smaller than X

This will probably be easy for regex magicians, however I can't seem to figure out a way with my limited knowledge.
I need a regex that would check if an alphanumeric string contains a number smaller than a number (16539065 in my case).
For example the following should be matched:
alpha16000000beta
foo300bar
And the following should not be matched:
foo16539066bar
Help please.
EDIT: I'm aware that it's inefficient, however I'm doing it in a cPanel Account Level filter, which only accepts regex. Unless I figure out a way for it to trigger a script instead, this would definitely need to be done with regex. :(
Your best option for this kind of operation is to use a capture group to get the number and then use whatever language you are using to do the comparison. If you absolutely have to use a regex to do this, it will be extremely inefficient. To do so, you will need to combine a lot of similar expressions:
\d{1,7} will find any numbers with 1 to 7 digits, which will always be less than 16539065
1653906[1-4] will catch the absolute maximum values accepted
165390[1-5]\d will catch the next range of acceptable values
1653[1-8]\d{3} will continue on the acceptable range
Repeat the above until you reach 1[1-5]\d{6}
Once you have all of those expressions, they can be combined using the 'or' operator. Keep in mind that using regular expressions in this manner is considered to be bad practice and creates hard to read code.
Bad Karma might kill me, but here is a working solution for your cases (letters then numbers then letters). It will not work for e.g. ab12cd34de.
There is not really a way to shortcode anything, just the long way. I'm using a negative lookahead to check, that the number is not bigger or equal to 16539065.
^\D*(?!0*(?:\d{9}|2\d{7}|1[7-9]\d{6}|16[6-9]\d{5}|165[4-9]\d{4}|16539[1-9]\d{2}|165390[7-9]\d|1653906[5-9]))\d+\D*$
It checks for the general format ^\D*\d+\D*$ and then rolls 16539065 down to it's parts.
Here's a little demo to play around: https://regex101.com/r/aV6yQ9/1

how do i write the regex for a limited range repetition

I am creating a form whereby the users can input a multi-value in a limited range
I am having trouble repeating the range as shown below, do i have to validate the comma as well and can i have the full regular expression solution for this?
I am allowing the user to input the value multiple times for a limited range of 0-1000 for 64 times or less
the input can be as follow:
1000,0,100,123,10,23,56,654,981
and here's my current regular expression for the range
(^(?:[0-9]|[1-9][0-9]|[1-9][0-9]{2}|1000)$)
Short answer:
^((1000|\d{1,3})(,|$)){1,64}
(Assuming you don't mind leading zeros. If you do, then change \d{1,3} to the more complex ([1-9][0-9]|[1-9])?[0-9].)
Long version:
We want to match (numbers in the range 0-1000) (repeated 1-64 times).
The first part can be done with (1000|\d{3}) (with the caveat noted above about leading zeros).
For the second part, we use a handy trick to do the comma-separation aspect: we say that each number must either be followed by a comma or the end of the string.
Note that there is a small weakness to this approach: it accepts trailing commas, e.g. 1,2,3, matches. If you're not okay, you can adapt by just adding, but it'll make the pattern longer:
^((1000|\d{1,3}),){0,63}(1000|\d{1,3})$
Note that I use an explicit {0,63} but many regex variants will accept the short form {,63} as well.
Also note that regex might not be the best solution for this - it might be better to just split the input string on commas and then iterate though the pieces, validating that each one is a number from 0-1000 and there are 64 or fewer pieces.

Regular Expression (consecutive 1s and 0s)

Hey I'm supposed to develop a regular expression for a binary string that has no consecutive 0s and no consecutive 1s. However this question is proving quite tricky. I'm not quite sure how to approach it as is.
If anyone could help that'd be great! This is new to me.
You're basically looking for alternating digits, the string:
...01010101010101...
but one that doesn't go infinitely in either direction.
That would be an optional 0 followed by any number of 10 sets followed by an optional 1:
^0?(10)*1?$
The (10)* (group) gives you as many of the alternating digits as you need and the optional edge characters allow you to start/stop with a half-group.
Keep in mind that also allows an empty string which may not be what you want, though you could argue that's still a binary string with no consecutive identical digits. If you need it to have a length of at least one, you can do that with a more complicated "or" regex like:
^(0(10)*1?)|(1(01)*0?)$
which makes the first digit (either 1 or 0) non-optional and adjusts the following sequences accordingly for the two cases.
But a simpler solution may be better if it's allowed - just ensure it has a length greater than zero before doing the regex check.

Is there a simple regex to compare numbers to x?

I want a regex that will match if a number is greater than or equal to an arbitrary number. This seems monstrously complex for such a simple task... it seems like you need to reinvent 'counting' in an explicit regex hand-crafted for the x.
For example, intuitively to do this for numbers greater than 25, I get
(\d{3,}|[3-9]\d|2[6-9]\d)
What if the number was 512345? Is there a simpler way?
Seems that there is no simpler way. regex is not thing that for numbers.
You may try this one:
\[1-9]d{6,}|
[6-9]\d{5}|
5[2-9]\d{4}|
51[3-9]\d{3}|
512[4-9]\d{2}|
5123[5-9]\d|
51234[6-9]
(newlines for clarity)
What if the number was 512345? Is there a simpler way?
No, a regex to match a number in a certain range will be a horrible looking thing (especially large numbers ranges).
Regex is simply not meant for such tasks. The better solution would be to "freely" match the digits, like \d+, and then compare them with the language's relational operators (<, >, ...).
In Perl you can use the conditional regexp construct (?(condition)yes-pattern) where the (condition) is (?{CODE}) to run arbitrary Perl code. If you make the yes-pattern be (*FAIL) then you have a regexp fragment which succeeds only when CODE returns false. Thus:
foreach (0 .. 50) {
if (/\A(\d+)(?(?{$1 <= 25})(*FAIL))\z/) {
say "$_ matches";
}
else {
say "$_ does not match";
}
}
The code-evaluation feature used to be marked as experimental but the latest 'perlre' manual page (http://perldoc.perl.org/perlre.html) seems to now imply it is a core language feature.
Technically, what you have is no longer a 'regular expression' of course, but some hybrid of regexp and external code.
I've never heard of a regex flavor that can do that. Writing a Perl module to generate the appropriate regex (as you mentioned in your comment) sounds like a good idea to me. In fact, I'd be surprised if it hasn't been done already. Check CPAN first.
By the way, your regex contains a few more errors besides the excess pipes Yuriy pointed out.
First, the "three or more digits" portion will match invalid numbers like 024 and 00000007. You can solve that by requiring the first digit to be greater than zero. If you want to allow for leading zeroes, you can match them separately.
The third part, 2[6-9]\d, only matches numbers >= 260. Perhaps you meant to make the third digit optional (i.e. 2[6-9]\d?), but that would be redundant.
You should anchor the regex somehow to make sure you aren't matching part of a longer number or a "word" with digits in it. I don't know the best way to do that in your particular situation, but word boundaries (i.e. \b) will probably be all you need.
End result:
\b0*([1-9]\d{2,}|[3-9]\d|2[6-9])\b

RegEx Numeric Check in Range?

I'm new to StackOverflow, so please let me know if there is a better way to ask the following question.
I need to create a regular expression that detects whether a field in the database is numeric, and if it is numeric does it fall within a valid range (i.e. 1-50). I've tried [1-50], which works except for the instances where a single digit number is preceded by a 0 (i.e. 06). 06 should still be considered a valid number, since I can later convert that to a number.
I really appreciate your help! I'm trying to learn more about regular expressions, and have been learning all I can from: www.regular-expressions.info. If you guys have recommendations of other sites to bone up on this stuff I would appreciate it!
Try this
^(0?[1-9])|([1-4][0-9])|(50)$
The idea of this regex is to break the problem down into cases
0?[1-9] takes care of the single digit case allowing for an optional preceeding 0
[1-4][0-9] takes care of all numbers from 10 to 49. This also allwows for a preceeding 0 on a single digit
50 takes care of 50
Regular expressions work on characters (in this case digits), not numbers. You need to have a separate pattern for each number of digits in your pattern, and combine them with | (the OR operator) like the other answers have suggested. However, consider just checking if the text is numeric with a regular expression (like [0-9]+) and then converting to an integer and checking the integer is within range.
You can't easily do range checking with regular expressions. You can -- with some work -- develop a pattern that recognizes a numeric range, but it's usually quite complex, and difficult to modify for a slightly different range.
You're better off breaking this into two parts.
Recognize the number pattern (^\d+$).
Check the range of that number in an application program.
^0?[1-50]{1,2}$