Regex to match a digit pattern with rotations - regex

What I'd like to match is the pattern 012345678901234567890123456789 but also 345678901234567890123456789012. Meaning, I want to match the first 30 characters of this pattern but I don't know in advance the first digit.
Is there a way to match any rotation of this pattern?

This could be done using alternation, however I'm not sure how efficient this is performance-wise:
^(?!.*(?:0[^1]|1[^2]|2[^3]|3[^4]|4[^5]|5[^6]|6[^7]|7[^8]|8[^9]|9[^0]))\d{30}$
See the online demo, where:
^ - Start string anchor.
(?! - Open a negative lookahead:
.* - 0+ characters other than newline.
(?: - Open non-capture group:
0[^1]|1[^2]|2[^3]|3[^4]|4[^5]|5[^6]|6[^7]|7[^8]|8[^9]|9[^0] - Basically assure that all digits are only followed by their appropriate successor using alternation.
) - Close non-capture group.
) - Close lookahead.
\d{30} - 30 Digits.
$ - End string anchor.

To ensure also the last digit within any group of characters and more positive (no negative lookahead but a positive one):
edit
to accommodate any sequence of the request it is actually better to
search for 29 digits followed by the right one
followed by one digit preceded by the right one:
line break added for readability only!
(0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=0)){29}
((?<=0)1|(?<=1)2|(?<=2)3|(?<=3)4|(?<=4)5|(?<=5)6|(?<=6)7|(?<=7)8|(?<=8)9|(?<=9)0)
This looks quite perfect now to me :)
first solution failed on 31 digits in I a row
(0(?=1|[^\d])|1(?=2|[^\d])|2(?=3|[^\d])|3(?=4|[^\d])|4(?=5|[^\d])|5(?=6|[^\d])|6(?=7|[^\d])|7(?=8|[^\d])|8(?=9|[^\d])|9(?=0|[^\d])){30}
this searches for 30 numbers 0 to 9 followed by their successor or not a number:
https://regex101.com/r/rTYByt/1

Related

Regex of dynamic block of characters

I have a block of number characters separated by '=' and the number range can be always different on both sides.
Example: 12345678999999=654784651321, next time it could be: 4567894135=456789211
I need help with finding suitable regex which select me always numbers between first 6 and last 4 digits of left side of block and then all numbers after 7th digit of right side of block:
123456[][][][]9999=6547846[][][][][]
Is this somehow possible?
[0-9]{6}([0-9]*)[0-9]{4}=[0-9]{7}([0-9]*)
Assuming the difficulty isn't matching a continuous set of digits, but rather matches each digit seperately try:
(?:^\d{6}|=\d{7}|\G)(?=\d{5,8}=|\d*$)\K\d
See an online demo
(?: - Open non-capture group for alternation;
^\d{6} - Match start-line anchor followed by 6 digits;
| - Or;
=\d{7} - Match a literal '=' followed by exactly 7 digits;
| - Or;
\G - Assert position at end of previous match or start of string;
(?=\d{5,8}=|\d*$) - Positive lookahead to assert possition is followed by either 5-8 digits upto an '=' or 0+ (greedy) digits upto end-line anchor;
\K - Reset starting point of previous reported match;
\d - A single digit.
Alternatively, if you have an environment that supports zero-width lookbehind like JavaScript or PyPi's regex package in Python, try:
(?:(?=\d{5,8}=)(?<=\d{6})|(?<==\d{7,}))\d
See an online demo
(?: - Open non-capture group for alternation;
(?=\d{5,8}=)(?<=\d{6}) - Positive lookahead to assert position is followed by 5-8 digits and an '=' but also preceded by at least 6 digits;
| - Or;
(?<==\d{7,}) - Positive lookbehind to assert position is preceded by an '=' followed by 7+ digits;
\d - A single digit.
// 6 NOT number or =
// ||
// \/
/[0-9]{6}[^\=0-9]*\=[^\=0-9]*[0-9]{4}/

Regex for a permutation of exactly 7 digits and 2 hyphens, without 2 consecutive hyphens

I a looking for a Regex to match a string which should:
start with a digit
'in-between' have a permutation of exactly 7 digits and 2 hyphens, without 2 consecutive hyphens
end with a sequence of digit, hyphen, digit
Match:
01-234-5678-9
01234-56-78-9
0123-4-5678-9
012-345-678-9
01-234567-8-9
01-234-5678-9
0-12345-678-9
0-123-45678-9
0-123-45678-9
01-23456-78-9
0-123456-78-9
0-1234567-8-9
No Match:
01-234-56789-0
01-234-567-8
01--2345678-9
01-2345678--9
0-1-23456789
-01-2345678-9
For now, I could not quite figure out how to match the 2 'in-between' hyphens: ^\d\d{7}\d-\d$
EDIT:
Thanks to the answers I had to this question, I was able to expand it to this other question regarding ISBN-10 and ISBN-13...
You can assert 7 digits and the digit - digit part at the end.
For the match there should be at least a single digit before and after the hyphen to prevent consecutive hyphens.
^\d(?=(?:-?\d){7}-?\d-\d$)\d*-\d+-\d*\d-\d$
^ Start of string
\d Match a single digit
(?= Positive lookahead
(?:-?\d){7} Match 7 digits separated by an optional -
-?\d-\d$ Match an optional - and the \d-\d$ at the end
) Close the lookahead
\d*-\d+-\d*\d-\d Match possible formats where all hyphens are separated by at least a single digit
$ End of string
Regex demo
My two cents:
^(?=.{11}-\d$)(?:\d+-){3}\d
See the online demo
^ - Start string anchor.
(?= - Open positive lookahead:
.{11}-\d$ - Any character other than newline 11 times followed by a hypen, a single digit and the end string anchor.
) - Close positive lookahead.
(?: - Open non-capture group:
\d+- - 1+ digit followed by an hyphen.
){3} - Close non-capture group and match three times.
\d - Match a single digit.
I guess alternatively even ^(?=.{13}$)(?:\d+-){3}\d$ would work.

Negative Lookahead not match suffix

I have an expression that is matching something, but am trying to get this not to match if it's followed by the suffix: one or more spaces, three dashes, one or more spaces, one or more digits, a slash, and finally one or more digits. Here is the expression:
(?<=(^|\s+))[A-Z]+[ ]+([0-9]+(\.[0-9]{1,3})?)/([0-9]+(\.[0-9]{1,3})?)(?!(\s+\-\-\-\s+[0-9]+/[0-9]+))
And here is the text:
January 10.5/13.5 --- 22/26 ---
It's matching January 10.5/13, but I don't want it to match anything.
As lookarounds are supported, you can change the positive lookbehind at the start to a negative lookbehind asserting a whitespace boundary to the left (?<!\S)
You can use .* to it to scan the whole line, instead of starting with 1+ more whitespace chars \s+
The negative lookahead (?!.*\s-{3}\s+[0-9]+/[0-9] asserts that what is on the right is not the suffix.
You can omit the quantifier + after the last character class, as it does not matter if there are 1 or more digits following...as long as it is not a digit.
Note that in the current pattern, the decimal part is an optional capturing group 2. If you want that whole value in group 1, you can make it an optional group.
(?<!\S)[A-Z]+[ ]+([0-9]+(\.[0-9]{1,3})?)/([0-9]+(\.[0-9]{1,3})?)(?!.*\s-{3}\s+[0-9]+/[0-9])
Regex demo

Custom Credit Card regex

I'm working with a custom credit card validator which has following conditions:
It must start with a 4,5 or 6.
It must contain exactly 16 digits.
It must only consist of digits (0-9).
It may have digits in groups of 4, separated by one hyphen -.
It must NOT use any other separator like ' ' , '_', etc.
It must NOT have 4 or more consecutive repeated digits.
I'm not able to find a regex fulfilling the last condition.
I have following regex for other conditions:
r'[456][0-9]{3}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4}':
For the last condition you could use a negative lookahead that asserts that what follows is not a digit followed by 3 or more times an optional hypen and a digit.
Explanation for the added part (?![-\d]*([0-9])(?:-?\1){3,})
(?!) Negative lookahead
[-\d]* Match zero or more times a digit or a hyphen
([0-9]) Capture a digit in a group
(?:-?\1){3,} Repeat 3 or more times in a non capturing group an optional hyphen -? followed by a backreference to the digit that is captured in group 1
) Close negative lookahead
Your regex with added anchors to assert the start ^ and the end $ of the line could look like:
^(?![-\d]*([0-9])(?:-?\1){3,})[456][0-9]{3}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4}$

Regular expressions REGEX 4 digits PIN code with at least one different than others

I tried different regex which I found here but they are not working.
for example:
1111 = false
1112 = true
It's my homework so I must do it in regex :)
You can use this regex:
^(\d)(?!\1+$)\d{3}$
Explanation:
^ - Match line start
(\d) - match first digit and capture it in back reference #1 i.e. \1
(?!..) is a negative lookahead
(?!\1+$) means disallow the match if first digit is followed by same digit (captured group) till end.
\d{3}$ match next 3 digit followed by line end
How about this?
(?=^\d{4}$)(\d)+(?!\1)\d\d*
The first look-ahead group (?=^\d{4}$) insists that the whole string consists of 4 digits.
The first capture group then matches any number of digits: (\d)+.
After this, there must be a digit is different to the first capture group: (?!\1)\d
Finally, there can be any number of digits trailing: \d*