I need regular expressions to match the below cases.
For case #2 I got inspired by a sample on regextester and created the following regex to match n
identical digits (to check for both numbers and letters replace 0-9
with A-Za-z0-9
):
const n = 3
const identicalAlphanumericRegEx = new RegExp("([0-9])" + "\\1".repeat(n - 1))
Regex to match three consecutive numbers or alphabets is "([0-9]|[aA-zZ])\1\1"
for the first question this works if you're ok with less regex
containsConsecutiveCharacters(str) {
for (let i = 0; i <= str.length - 3; i++) {
var allthree = str[i] + str[i + 1] + str[i + 2];
let s1 = str.charCodeAt(i);
let s2 = str.charCodeAt(i + 1);
let s3 = str.charCodeAt(i + 2);
if (
/[a-zA-Z]+$/.test(allthree) &&
(s1 < s2 && s2 < s3 && s1+s2+s3-(3*s1) === 3)
) {
return true;
}
}
}
If you have lower bound (3) and upper bound regexString can be generated as follows
public class RegexBuilder {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
int seqStart = 3;
int seqEnd = 5;
buildRegex(sb, seqStart, seqEnd);
System.out.println(sb);
}
private static void buildRegex(StringBuilder sb, int seqStart, int seqEnd) {
for (int i = seqStart; i <= seqEnd; i++) {
buildRegexCharGroup(sb, i, '0', '9');
buildRegexCharGroup(sb, i, 'A', 'Z');
buildRegexCharGroup(sb, i, 'a', 'z');
buildRegexRepeatedString(sb, i);
}
}
private static void buildRegexCharGroup(StringBuilder sb, int seqLength,
char start, char end) {
for (char c = start; c <= end - seqLength + 1; c++) {
char ch = c;
if (sb.length() > 0) {
sb.append('|');
}
for (int i = 0; i < seqLength; i++) {
sb.append(ch++);
}
}
}
private static void buildRegexRepeatedString(StringBuilder sb, int seqLength) {
sb.append('|');
sb.append("([a-zA-Z\\d])");
for (int i = 1; i < seqLength; i++) {
sb.append("\\1");
}
}
}
Output
012|123|234|345|456|567|678|789|ABC|BCD|CDE|DEF|EFG|FGH|GHI|HIJ|IJK|JKL|KLM|LMN|MNO|NOP|OPQ|PQR|QRS|RST|STU|TUV|UVW|VWX|WXY|XYZ|abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz|([a-z\d])\1\1|0123|1234|2345|3456|4567|5678|6789|ABCD|BCDE|CDEF|DEFG|EFGH|FGHI|GHIJ|HIJK|IJKL|JKLM|KLMN|LMNO|MNOP|NOPQ|OPQR|PQRS|QRST|RSTU|STUV|TUVW|UVWX|VWXY|WXYZ|abcd|bcde|cdef|defg|efgh|fghi|ghij|hijk|ijkl|jklm|klmn|lmno|mnop|nopq|opqr|pqrs|qrst|rstu|stuv|tuvw|uvwx|vwxy|wxyz|([a-z\d])\1\1\1|01234|12345|23456|34567|45678|56789|ABCDE|BCDEF|CDEFG|DEFGH|EFGHI|FGHIJ|GHIJK|HIJKL|IJKLM|JKLMN|KLMNO|LMNOP|MNOPQ|NOPQR|OPQRS|PQRST|QRSTU|RSTUV|STUVW|TUVWX|UVWXY|VWXYZ|abcde|bcdef|cdefg|defgh|efghi|fghij|ghijk|hijkl|ijklm|jklmn|klmno|lmnop|mnopq|nopqr|opqrs|pqrst|qrstu|rstuv|stuvw|tuvwx|uvwxy|vwxyz|([a-z\d])\1\1\1\1
I disagree, case 1 is possible to regex, but you have to tell it the sequences to match... which is kind of long and boring:
/(abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz|012|123|234|345|456|567|678|789)+/ig
http://regexr.com/3dqln
I was discussing this with a coworker and we think we have a good solution for #1.
To check for abc or bcd or ... or 012 or 123 or even any number of sequential characters, try:
.*((a(?=b))|(?:b(?=c))|(?:c(?=d))|(?:d(?=e))|(?:e(?=f))|(?:f(?=g))|(?:g(?=h))|(?:h(?=i))|(?:i(?=j))|(?:j(?=k))|(?:k(?=l))|(?:l(?=m))|(?:m(?=n))|(?:n(?=o))|(?:o(?=p))|(?:p(?=q))|(?:q(?=r))|(?:r(?=s))|(?:s(?=t))|(?:t(?=u))|(?:u(?=v))|(?:v(?=w))|(?:w(?=x))|(?:x(?=y))|(?:y(?=z))|(?:0(?=1))|(?:1(?=2))|(?:2(?=3))|(?:3(?=4))|(?:4(?=5))|(?:5(?=6))|(?:6(?=7))|(?:7(?=8))|(?:8(?=9))){2,}.*
The nice thing about this solution is if you want more than 3 consecutive characters, increase the {2,}
to be one less than what you want to check for.
the ?:
in each group prevents the group from being captured.