Regex max number 11 and must 2 digits - regex

I have a validation expression i'm trying to figure out. First, I want the user to only be allowed to enter the max number of 11...not 11 characters but the number allow is the max that can be entered. I got that to work with the code below and works fine.
ValidationExpression="^([1-9]|[0-1][0-1])$"
However, I want the user to also be forced to use 2 digits. For example, instead of 1 they need to enter 01. I've tried different ways of doing this but can't seem to get it to work.
I tried this as well but that didn't work either.
ValidationExpression="^([1-9]|[0-1][0-1])${2}"

If you need to perform this in a single step (i.e. you can't do a < and > check as well as a regex) then this should do it:
ValidationExpression="^(?:0\d|1[01])$"
Or, if your language doesn't recognise the \d symbol:
ValidationExpression="^(?:0[0-9]|1[01])$"
"Match either (0 followed by any digit) or (1 followed by 0 or 1), anchored at the beginning and end of the input string."

To match padded 2-digit numbers from 01 to 12 you may use
ValidationExpression="^(0[1-9]|1[01])$"
See the regex demo.
The expression matches:
^
( - start of a group (here, a capturing group is used for better readability, a non-capturing one can also be used)
0 - zero
[1-9] - 1 to 9 digit
| - or
1 - 1
[01] - 0 or 1 digit
) - end of group
$ - end of string.

You can use this regex
/\b(?:[0][\d]|[1][01])\b/
This says enter a number 0 followed by 0-9 or enter 1 followed by 0 or 1. It is bounded on both sides by word boundaries and it is a non-capturing group. Try it out here.

Related

Checking min no of characters in capturing group in Regex

I have a question in regex
I am dealing with numbers 0 and 1 only
I have 10 digit number grouped into 4 as below
([01]{2})([01]{4})([01]{2})([01]{2})
I need to match all those numbers with min 2 1's in the second group which is ([01]{4}) , no matter how many 0's or 1's other groups are having. I am interested only in the second group
For example, these are the potential matches are
0000110000
0011000000
0001100000
0000110000
I tried using positive look ahead like :
^(\d{2})((?=\d*1{2,}\d*)(\d{4}))(\d{2})(\d{2})
but this is matching even
0000000011
Any help is deeply appreciated
If the two 1s are not necessarily consecutive in Group 2, you can use
^([01]{2})(?=(?:[01]*1){2}[01]{4,6}$)([01]{4})([01]{2})([01]{2})$
See the regex demo
Details:
^ - start of string
([01]{2}) - Group 1: two occurrences of 1 or 0
(?=(?:[01]*1){2}[01]{4,6}$) - immediately to the right of the current location, there must be two occurrences of any zero or more 0 or 1 chars followed with 1 and then there must be four, five or six 1 or 0 chars till the end of string
([01]{4}) - Group 2: four occurrences of 1 or 0
([01]{2}) - Group 3: two occurrences of 1 or 0
([01]{2}) - Group 4: two occurrences of 1 or 0
$ - end of string.
If the ones need to be consecutive (as per your sample data), maybe you can use:
^(?=[01]{2,4}11)[01]{10}$
See the online demo. The idea here is that you would match 2-4 zero's or 1's upto a sequence of two ones. It makes sense if you realise the only combinations that are allowed would have the minimum of two 1's ("11") sequence after exactly 2-4 other digits.
^ - Start line anchor.
(?=[01]{2,4}11) - Open positive lookahead to look for 2-4 characters from our characters class upto "11".
[01]{10} - Match exactly 10 characters from our character class.
$ - End line anchor.
If need be you can change the [01]{10} pieces where you'd use capture groups.
EDIT:
If they don't have to be consecutive, maybe you can work with:
^[01]{2}(?=[01]{8}$)([01]{0,2}1[01]{0,2}1[01]{0,2})[01]{4}$
See the online demo.
Or less verbose:
^(?=[01]{10}$)(..)(.*1.*1.*)(..)(..)$
See the demo
Not a job for regex but for bitwise operators:
(in PHP):
$nums = [
'0000110000',
'0011000000',
'0001100000',
'1000110000',
'0000000110',
'0001000000'
];
foreach ($nums as $num) {
if ( !in_array((bindec($num) >> 4) & 15, [0, 1, 2, 4, 8]) )
echo $num, PHP_EOL;
}
You can probably do that in any language.
If a positive lookahead is supported, you could also assert that group 2 has as least 11 using a positive lookahead.
^([01]{2})(?=[01]{0,2}11)([01]{4})([01]{2})([01]{2})$
^ Start of string
([01]{2}) - Group 1: two occurrences of 1 or 0
(?= Positive lookahead
[01]{0,2}11 Match 0-2 times either 0 or 1 and match 11
) Close lookahead
([01]{4}) - Group 2: four occurrences of 1 or 0
([01]{2}) - Group 3: two occurrences of 1 or 0
([01]{2}) - Group 4: two occurrences of 1 or 0
$ - end of string.
Regex demo
Or you can write out all 3 alternatives matching 11
^([01]{2})(11[01][01]|[01]11[01]|[01][01]11)([01]{2})([01]{2})$
Regex demo

RegEx to check 24 hours time format fails

I have the following RegEx that is supposed to do 24 hours time format validation, which I'm trying out in https://rubular.com
/^[0-23]{2}:[0-59]{2}:[0-59]{2}$/
But the following times fails to match even if they look correct
02:06:00
04:05:00
Why this is so?
In character classes, you're supposed to denote the range of characters allowed (in contrast to the numbers you want to match in your example). For minutes and seconds, this is relatively straight-forward - the following expression
[0-5][0-9]
...will match any numerical string from "00" to "59".
But for the hours, you need to two separate expressions:
[01][0-9]|2[0-3]
...one to match "00" to "19" and one to match "20" to "23". Due to the alternative used (| character), these need to be grouped, which adds another bit of syntax (?:...). Finally we're just adding the anchors ^ and $ for beginning and end of string, which you already had where they belong.
^(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$
You can check this solution out at regex101, if you like.
Your problem is that you understand characters ranges wrong: 0-23 doesn't mean "match any number from 0 to 23", it means: 0-2- match one digit: 0,1 or 2, then match 3.
Try this pattern: (?:[01][0-9]|2[0-3])(?::[0-5][0-9]){2}
Explanation:
(?:...) - non-capturing group
[01][0-9]|2[0-3] - alternation: match whether 0 or one followed by any digits fro 0 to 9 OR 2 followed by 0, 1, 2 or 3 (number from 00-23)
(?::[0-5][0-9]){2} - match : and [0-5][0-9] (basically number from 00-59) twice
Demo
use this (([0-1]\d|[2][0-3])):(([0-5][0-9])):(([0-5][0-9]))
Online demo

Regular expression to get positive integer and -1

Below is the text I hope to match:
00000001,00000002,00000003
It works fine with ((([-1-9]+),)+)?[-1-9]+.
But it didn't match -1. The expression must not match with -2 or anything else except -1.
You may use
^(?:0*[1-9][0-9]*|-1)(?:,(?:0*[1-9][0-9]*|-1))*$
See the regex demo.
Pattern details:
^ - start of string
(?:0*[1-9][0-9]*|-1) - a non-capturing group matching...
0*[1-9][0-9]* - zero or mor 0 chars, followed with a non-zero digit followed with any 1 or more digits
| - or
-1 - a -1 substring
(?:,(?:0*[1-9][0-9]*|-1))* - a non-capturing group quantified with * (0 or more) quantifier matching 0 or more repetitions of:
, - a comma
(?:0*[1-9][0-9]*|-1) - same subpattern as in the beginning (-1 or a non-zero number with no fractions)
$ - end of string.
[-1-9]+ doesn't match what you're expecting it to match. It matches for example: "-31-23", which is obviously not a number.
A simple regex like:
(?:^-1)$|^[0-9]+
will match "-1", or any positive integer (including 0001, 00000002, etc...).
Also, depending on the language you're using, it would be simpler to use the language's features to decide if the number is "-1" or any other positive number.
As your state that ((([-1-9]+),)+)?[-1-9]+ works fine which captures a positive integer and looking at the title of the question, you might use this regex using alternation to capture -1 or only positive integers including 0 or 00000 from a string which could be preceded with zeroes.
The positive integers will be captured in group 1.
-[02-9][0-9]*|0*(-?[0-9]+)
Details
- Match literally
[02-9][0-9]* Match a 0 or digits 2-9 followed by zero or more times a digit. Note that the - is not part of the character class or else --- would also match.
| Or
0* Match zero or more times a zero
(-?[0-9]+) Capture in group 1 an optional hyphen followed by one or more times a digit

Regex limiting a number string

I am trying to figure out how to use regex to pass a 6 digit number string. My trouble is the string can be any 6 digits, unless it starts with 12. So the first digit can be 1 but not if second digit is 2. The second digit can be 2, but not if the first is 1.
I tried this, ([^1])([^2])(\d{4}) but that does not take into account both digits, so it will block anything with a 2 in the second spot.
Thank you for any help.
You may use
^([02-9][0-9]|[0-9][013-9])[0-9]{4}$
See the regex demo
Details:
^ - start of string
([02-9][0-9]|[0-9][013-9]) - either of the two alternatives:
[02-9][0-9] - any digit but 1 and then any digit
| - or
[0-9][013-9] - any digit and then any digit but 2
[0-9]{4} - any 4 digits
$ - end of string.
Another way is to use a negative lookahead:
^(?!12)[0-9]{6}$
See another demo. Here, (?!12) fails the match if the first 2 digits are 12. The [0-9]{6} will match 6 digits.
Depending on the regex library/method, ^/$ anchors may not be required. Lookaheads are not always supported, too.

Why does this not match my example?

as I go through the regex101 quiz/lessons, I am supposed to match an IP address (without leading zeros).
Now the following
^[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+$
matches 23.34.7433.33
but fails to match single digit numbers like 1.2.3.4
Why is this so, when my + is supposed to match "1 to infinite" times...?
You are in fact matching more than 2 digits for each number in the IP address because you have:
[^0]+[0-9]+
[^0]+ matches at least one character, and [0-9]+ matches at least 1 character. Both will match 'at least 2 characters' (characters being in scope of the character classes).
Also 23.34.7433.3 doesn't match your regex for the reason I stated above.
And you might try this regex for the purpose you stated:
^(?:[1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}$
[1-9][0-9]{0,2} will match up to 3 digits, with a non leading 0.
EDIT: You mentioned in a comment that 0.0.0.0 (single digit zeroes) are to be accepted as well. The modified regex from above would be:
^(?:(?:[1-9][0-9]{0,2}|0)\.){3}(?:[1-9][0-9]{0,2}|0)$
Assuming you want to check an IPv4, I suggest you this pattern:
^(?<nb>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])(?>\.\g<nb>){3}$
I have defined a named subpattern nb to make the pattern shorter, but if you prefer, you can rewrite all and replace \g<nb>:
^(?>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])(?>\.(?>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])){3}$
Numbers greater than 255 are not allowed.
pattern details:
The goal is to describe what is allowed:
numbers with 3 digits that begins with "2" can be followed by a digit in [0-4] and a digit in [0-9] OR by 5 and a digit in [0-5] because it can exceed 255.
numbers with 3 digits that begins with "1" can be followed by any two digits.
any number with 2 digits that doesn't begin with "0"
any number with 1 digit (zero included)
If I add one by one these rules, I obtain
2(?>[0-4][0-9]|5[0-5])
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2}
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2} | [1-9][0-9]
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2} | [1-9][0-9] | [0-9]
Now I have a definition for allowed numbers. I can reduce a little the size of the pattern replacing [1-9][0-9] | [0-9] by [1-9]?[0-9]
Then you only have to add the dot repeat the subpattern four times: x.x.x.x
But since there is only three dots, I write the first number and I repeat 3 times a group that contains a dot and a number:
2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9] # the first number
(?>\.2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9]){3} # the group repeated 3 times
To be sure that the string doesn't contain anything else that the IP I described, I add anchors for the start of string ^ and for the end of string $, then the string begins and ends with the IP.
To reduce the size of a pattern you can define a named group which allows to reuse the subpattern it contains,
Then you can rewrite the pattern like this:
^
(?<nb> 2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9] ) # named group definition
(?> \. \g<nb> ){3} # \g<nb> is the reference to the subpattern named nb
$
[0-9]+ should be [0-9]*
* matches 0 or more.
+ matches 1 or more.
You already have the case [^0] <--- this actually wrong because it will match letters also.
besides that it will match the first character that's NOT zero then at least one number after that.
It should be written as
[1-9][0-9]*
This essentially checks the first letter and sees if its a number that's between 1-9 then the next numbers(0 nums to infinite nums) after that is a number 0-9.
Then this will come out to.
^[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*$
Edit live on Debuggex
cleaning it up.
^(?:[1-9][0-9]*\.){3}[1-9][0-9]*$
this should work...
^(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*|[0-9])$
cleaned up.
^(?:(?:[1-9][0-9]*|0)\.){3}(?:[1-9][0-9]*|0)$
Your regex would match ABCDEFG999.FOOBSR888 etc, because [^0] is any character other than a zero, and bith character classes are required by the +.
I think you want this:
^[1-9]\d*(\\.[1-9]\d*){3}$
having replaced various verbose expressions with their equivalent, this is 4 groups of digits each starting with a non-zero.
Actually the problem is far more complicated, because your approach (once corrected) allows 999.999.999.999, which is not a valid IP.
It might be because you need at least two digits between two dots '.'
try using this pattern: ^[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*$
to match ip address you should use this pattern:
\b(?:\d{1,3}.){3}\d{1,3}\b
taken from here:
http://www.regular-expressions.info/examples.html