REGEX for matching number with two and three numbered patterns together - javascript

I have an array of 5 numbers, I'd like to match as long as there are three of the same number and two of the same different number in the array, placement does not matter. Number sequences can be any random string of 5 numbers between 1 - 5.
Examples of matches would be:
33322
24422
52225
44111
54545
*basically any grouping of 2 and 3 of the same numbers needs to match.
Best I've come up with so far:
^([0-9])\1{2}|([0-9])\1{1}$
I am not so good with regex, any help would be greatly appreciated.

You can use
^(?=[1-5]{5}$)(?=.*(\d)(?:.*\1){2})(?=.*(?!\1)(\d).*\2)\d+$
^(?=.*(\d)(?:.*\1){2})(?=.*(?!\1)(\d).*\2)[1-5]{5}$
See the regex demo.
If you want to allow any digits, replace [1-5] with \d.
Details:
^ - start of string
(?=[1-5]{5}$) - there must be five digits from 1 to 5 till end of string (this lookahead makes non-matching strings fail quicker)
(?=.*(\d)(?:.*\1){2}) - a positive lookahead that requires any zero or more chars as many as possible, followed with a digit (captured into Group 1) and then two sequences of any zero or more chars as many as possible and the same digit as captured into Group 1 immediately to the right of the current location
(?=.*(?!\1)(\d).*\2) - a positive lookahead that requires any zero or more chars as many as possible, followed with a digit (captured into Group 2) that is not equal to the digit in Group 1, and then any zero or more chars as many as possible and the same digit as captured into Group 2 immediately to the right of the current location
\d+ - one or more digits
$ - end of string.

There are many ways to do that. One is to match the following regular expression.
^(?=([1-5]).*\1)(?=.+(?!\1)([1-5]).*\2)(?:\1|\2){5}$
The idea is as follows.
use a positive lookahead to match and save to capture group 1 the first digit and require it to appear at least twice;
use a positive lookahead to match and save to capture group 2 a digit that is different from the digit in capture group 1 and require it to appear at least twice;
match a five-character string that contains only the digits in the two capture groups.
Demo
The regular expression can be broken down as follows.
^ # match beginning of string
(?= # begin a positive lookahead
([1-5]) # match a digit 1-5 and save to capture group 1
.* # match zero or more characters
\1 # match the digit in capture group 1
) # end positive lookahead
(?= # begin a positive lookahead
.+ # match one or more characters
(?!\1) # next character is not the digit in capture group 1
([1-5]) # match a digit 1-5 and save to capture group 2
.* # match zero or more characters
\2 # match the digit in capture group 2
) # end positive lookahead
(?:\1|\2){5}$ # match a 5-character string comprised of the digits
# in the two capture groups
Here's a second expression that could be used:
^(?=([1-5])\1*(?!\1)([1-5])(?:\1*\2){1,2}\1*$).{5}$
Demo

Related

Regex - Allow one or two alphabet and its can be at anywhere in string

I want regex which can fulfill below requirement:
Between 6 and 10 total characters
At least 1 but not more than 2 of the characters need to be alpha
The alpha characters can be anywhere in the string
We have tried this but not working as expected : (^[A-Z]{1,2}[0-9]{5,8}$)|(^[A-Z]{1}[0-9]{4,8}[A-Z]{1}$)|(^[0-9]{4,8}[A-Z]{1,2}$)|([^A-Z]{3}[0-9]{6,9})
Can anyone please help me to figure it out?
Thanks
You can assert the length of the string to be 6-10 char.
Then match at least a single char [A-Z] between optional digits, and optionally match a second char [A-Z] between optional digits.
^(?=[A-Z\d]{6,10}$)\d*[A-Z](?:\d*[A-Z])?\d*$
^ Start of string
(?=[A-Z\d]{6,10}$) Positive lookahead to assert 6-10 occurrences of A-Z or a digit
\d*[A-Z] Match optional digits and then match the first [A-Z]
(?:\d*[A-Z])? Optionally match optional digits and the second [A-Z]
\d* Match optional digits
$ End of string
See a regex demo.
One option is to use the following regular expression:
^(?=.*[a-z])(?!(?:.*[a-z]){3})[a-z\d]{6,10}$
with the case-indifferent flag i set.
Demo
This expression reads, "Match the beginning of the string, assert the string contains at least one letter, assert the string does not contain three letters and assert the string contains 6-10 characters, all being letters or numbers".
The various parts of the expression have the following functions.
^ # match the beginning of the string
(?= # begin a positive lookahead
.*[a-z] # match zero or more characters and then a letter
) # end positive lookahead
(?! # begin a negative lookahead
(?: # begin a non-capture group
.*[a-z] # match zero or more characters and then a letter
){3} # end non-capture group and execute it 3 times
) # end negative lookahead
[a-z\d]{6,10} # match 6-10 letters or digits
$ # match end of string
Note that neither of the lookaheads advances the string pointer maintained by the regex engine from the beginning of the string.

regex to extract number and date from string

I'm trying to extract date, percentage or number from string. Strings can be:
the response value 10 (from here I want to extract 10)
the response value 10/12/2014 (from here I want to extract 10/12/2014)
the response value 08/2015 (from here I want to extract 08/2015)
I've written regex as (?:\d{2}\/\d{4}|\d{2}(?:\/\d{2}\/\d{4})?) Regex is satisfying 12/12/2014, 10, 02/2012.
I'm also trying to modifying same regex to get 10, 08/2015 and 10/10/2015 but not getting how to get.
How can this be achieved?
To match your example data, you could use an alternation matching either 2 digits / 4 digits, or match 2 digits with an optional part that matches 2 digits and 4 digits.
\b(?:\d{2}\/\d{4}|\d{2}(?:\/\d{2}\/\d{4})?)\b
Explanation
\b Word boundary, prevent the word char being part of a larger word
(?: Non capture group
\d{2}\/\d{4} Match 2 digits/4 digits
| Or
\d{2} Match 2 digits
(?:\/\d{2}\/\d{4})? Optionally match /2 digits/4 digits
) Close group
\b Word boundary
Regex demo
Note that 2 and 4 digits could also match 99 and 9999. If you want to make your match more specific, this page can be helpful https://www.regular-expressions.info/dates.html
const pattern = /\b(?:\d{2}\/\d{4}|\d{2}(?:\/\d{2}\/\d{4})?)\b/;
[
"the response value 10",
"the response value 10/12/2014",
"the response value 08/2015"
].forEach(s => console.log(s.match(pattern)[0]));
Just for fun (regex is fun) an alternative to the accepted answer:
\b(?:(?:\d\d\/){1,2}\d{4}|\d\d)\b
See the Online Demo
\b - Match a word boundary.
(?: - 1st Non-capturing group.
(?: - 2nd Non-capturing group.
\d\d\/ - Match two digits and a literal forward slash.
){1,2} - Close 2nd non-capturing group and use it once or twice.
\d{4} - Match four digits.
| - Alternation (OR).
\d\d) - Two digits and close 1st non capturing group.
\b - Match a word boundary.
Maybe we can do this even without alternation:
\b\d\d(?:(?:\/\d\d){1,2}\d\d)?\b
See the Online Demo
\b - Match a word boundary.
\d\d - Match two digits.
(?: - 1st Non-capturing group.
(?: - 2nd Non-capturing group.
\/\d\d - Match a literal slash and two digits.
){1,2} - Close 2nd non-capturing group and use it once or twice.
\d\d - Match two digits.
)? - Close 1st non-capturing group and make it optional.
\b - Match a word boundary.
Match method supports regExp and will return an array with the items you are looking for:
var date = "12/12/2014"
var arr = date.match(/(\d{2})[\/](\d{2})[\/](\d{4})/);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
console.log(arr[3]);

How to create Regex to filter out results with few complex conditions regarding length, case and classes of characters

I have the following filtered:
2 digits (?=..*\d)
2 uppercase characters (?=..*[a-z])
2 lowercase characters (?=..*[A-Z])
10 to 63 characters .{10,63}$
Which translates to:
(?=.{2,}\d)(?=..*[a-z])(?=..*[A-Z]).{10,63}
Then I want to exclude a word starting with the letter u, and ending with three to six digits:
([uU][0-9]{3,6})
However, how can I merge these two patterns to do the following:
It should not allow the following because it respectively:
# does not have the required combination of characters
aaaaaaaaaaaaaaa
# is too long
asadsfdfs12BDFsdfsdfdsfsdfsdfdsfdsfdfsdfsdfsdfsdsfdfsdfsdfssdfdfsdfssdfdfsdfssdfdfsdfsdfsdfsdfsfdsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs
# contains the pattern that shouldn't be allowed
U0000ABcd567890
ABcd56U00007890
D4gF3U432234
D4gF3u432234
ABcd567890U123456
should allow the following:
# it has the required combination of characters
ABcd5678990
ABcd567890
# does contain a part of the disallowed pattern (`([uU][0-9]{3,6})`), but does not fit that pattern entirely
ABcd567890U12
ABcd5U12abcdf
s3dU00sDdfgdg
ABcd56U007890
Created and example here: https://regex101.com/r/4b2Hu9/3
In your pattern you make use of a lookahead (?=..*\d) which has a different meaning than you assume.
It means if what is directly on the right is 2 or more times any char except a newline followed by a single digit and the same for the upper and lowercase variants.
You could update your pattern to:
^(?!.*[uU]\d{3,6})(?=(?:\D*\d){2})(?=(?:[^a-z]*[a-z]){2})(?=(?:[^A-Z]*[A-Z]){2}).{10,63}$
In parts
^ Start of string
(?!.*[uU]\d{3,6}) Negative lookahead, assert not u or U followed by 3-6 digits
(?=(?:\D*\d){2}) Assert 2 digits
(?=(?:[^a-z]*[a-z]){2}) Assert 2 lowercase chars
(?=(?:[^A-Z]*[A-Z]){2}) Assert 2 uppercase chars
.{10,63} Match any char except a newline 10-63 times
$ End of string
Regex demo
First, the way to ensure that the string contains, for example, two digits would be to use a positive lookahead:
(?=.*\d.*\d)
You can generalize this to your other filters.
To make sure the string contains 10 - 63 characters:
.{10,63}
You say you do not want the string to begin with u or U followed by 3 to 6 digits (presumbaly 7 digits is okay), use a negative lookahead:
(?![uU]\d{3,6}\D)
The \D is required to make sure that if there is a 7th digit, then the string will be accepted.
Putting it all together:
r'^(?=.*\d.*\d)(?=.*[a-z].*[a-z])(?=.*[A-Z].*[A-Z])(?![uU]\d{3,6}\D).{10,63}$'

regex to only allow an input to 3 decimal places with 0.001 being the smallest number possible, not 0

I am trying to write a regex to allow a user enter a positive number and to 3 decimal places. My regex looks like this, however, it isn't working as I would like.
/\d*[1-9](\.\d{0,3})?/
This allows the user to enter 1.000 as the smallest number, however, it doesn't allow a user to enter 0.001 which should be the smallest number possible to enter into the input.
Does anyone know what the regex should be to solve this?
Your code has another issue where it can not match 10 since you are not allowing the ones place to be 0.
You need to use some or statements
const re = /(^([1-9]|\d{2,})(\.\d{0,3})?|0\.\d{0,2}[1-9])$/
const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1"]
tests.forEach(n => console.log(n, re.test(n)))
const re = /^(?!0+(?:\.0+)?$)\d+(?:\.\d+)?$/
const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1","1.22","1.222"]
tests.forEach(n => console.log(n, re.test(n)))
Explanation:
^ # beginning of string
(?! # negative lookahead, make sure we haven't after:
0+ # 1 or more zero
(?: # start non capture group
\. # a dot
0+ # 1 or more zero
)? # end group, optional
$ # end of string
) # end lookahead
\d+ # 1 or more digits
(?: # start non capture group
\. # a dot
\d+ # 1 or more digits
)? # end group, optionnal
$ # end of string
Personally I would just check for 0 and make the regex a lot simpler, but here is a solution, where the required decimal places can be adjusted by changing {1,3}.
The jist of this regex is that we allow any number greater than two digits , then allow only 1-9 for one digit, then optionally require up to 1 decimal with 1-3 digits afterwards.
const r = /^((([0-9]{2,}){1}|[1-9]{1})(\.[0-9]{1,3}){0,1})$/;
const tests = ['1','2','0','1.001','1.001.1','999.001','9.01','9.0100','abc'];
tests.forEach(t=>console.log(t,r.test(t)));
Another option is to use a negative lookahead to assert from the start of the string what is on the right is neither a dot or zero repeated until the end of the string:
^(?![0.]+$)\d+(?:\.\d{1,3})?$
See a Regex demo
Explanation
^ Start of the string
(?![0.]+$) Negative lookahead to assert what is on the right is not what is listed in the character class repeated 1+ times until the end of the string
\d+ Match 1+ times a digit
(?:\.\d{1,3})? Optional non capturing group which matches a dot and 1+ times a digit
$ End of the string
const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1","1.22","1.222"]
tests.forEach(n => console.log(parseFloat(n) >= 0.001))
I really think this is being overthought.
The answer is here.
([1-9]\.[0-9][0-9][0-9]|[0]\.[1-9][0-9][0-9]|[0]\.[0][1-9][0-9]|[0]\.[0][0][1-9])
This should match 0.001~9.999

Regex validation for mixed digits for a max of 6 characters

I need a regex validation for mixed length, a total length of 6 characters in that 4-6 characters in caps/numbers and 0-2 spaces.
I tried like
^[A-Z0-9]{4,6}+[\s]{0,2}$
but it results in a max length of 8 characters, but I need a max of 6 characters.
If the alphanumeric chars should only appear at the start of the string and the whitespaces can appear at the end (i.e. the order of the alphanumerics and whitespaces matters), you may use
/^(?=.{6}$)[A-Z0-9]{4,6}\s*$/
See the regex demo
Details
^ - start of string
(?=.{6}$) - the string length is restricted to exactly 6 non-line break chars
[A-Z0-9]{4,6} - 4, 5 or 6 uppercase ASCII letters or digits
\s* - 0+ whitespaces (but actually, only 0, 1 or 2 will be possible to add as the total length is already validated with the lookahead)
$ - end of string.
If you want to match the alphanumeric and whitespaces anywhere inside the string, you need a lookaround based regex like
^(?=(?:[^A-Z0-9]*[A-Z0-9]){4,6}[^A-Z0-9]*$)(?=(?:\S*\s){0,2}\S*$)[A-Z0-9\s]{6}$
See the regex demo
Details
^ - start of string
(?=(?:[^A-Z0-9]*[A-Z0-9]){4,6}[^A-Z0-9]*$) - a positive lookahead that requires the presence of 4 to 6 letters or digits anywhere inside the string
(?=(?:\S*\s){0,2}\S*$) - a positive lookahead that requires the presence of 0 to 2 whitespaces anywhere inside the string
[A-Z0-9\s]{6} - 6 ASCII uppercase letters, digits or whitespaces
$ - end of string.
To shorten the pattern, the second lookahead can be written as (?!(?:\S*\s){3}), it will fail the match if there are 3 whitespace chars anywhere inside the string. See the regex demo.
You can use | characters to accommodate several cases into one.
const regex = /(^[A-Z0-9]{4}\s{2}$)|(^[A-Z0-9]{5}\s$)|(^[A-Z0-9]{6}$)/g;
alert(regex.test(prompt('Enter input, including space(s)')));
If you want to match zero, one or two spaces at the end, you could use an alternation for those 3 cases.
^(?:[A-Z0-9]{4}[ ]{2}|[A-Z0-9]{5}[ ]|[A-Z0-9]{6})$
Regex demo
Explanation
^ Assert the start of the string
(?: Non capturing group
[A-Z0-9]{4}[ ]{2} Match uppercase or digit 4 times followed by 2 spaces
| Or
[A-Z0-9]{5} Match uppercase or digit 5 times followed by 1 space
| Or
[A-Z0-9]{6} Match uppercase or digit 6 times
) Close non capturing group
$ Assert the end of the string

Categories