sandy0093
sandy0093

Reputation: 577

Regular Expression to match 3 or more Consecutive Sequential Characters and Consecutive Identical Characters

I need regular expressions to match the below cases.

  1. 3 or more consecutive sequential characters/numbers; e.g. 123, abc, 789, pqr, etc.
  2. 3 or more consecutive identical characters/numbers; e.g. 111, aaa, bbb, 222, etc.

Upvotes: 42

Views: 137270

Answers (15)

Milad Naseri
Milad Naseri

Reputation: 4118

I don't think you can (easily) use regex for the first case. The second case is easy though:

Pattern pattern = Pattern.compile("([a-z\\d])\\1\\1", Pattern.CASE_INSENSITIVE);

Since \\1 represents part matched by group 1 this will match any sequence of three identical characters that are either within the range a-z or are digits (\d).

Update

To be clear, you can use regex for the first case. However, the pattern is so laborious and ridiculously convoluted that you are better off not doing it at all. Especially if you wanted to REALLY cover all the alphabet. In that case you should probably generate the pattern programmatically by iterating the char codes of the Unicode charset or something like that and generate groupings for every three consecutive characters. However, you should realize that by having generated such a large decision tree for the pattern matcher, the marching performance is bound to suffer (O(n) where n is the number of groups which is the size of the Unicode charset minus 2).

Upvotes: 31

Gaurav Singh
Gaurav Singh

Reputation: 39

Regex to match three consecutive numbers or alphabets is "([0-9]|[aA-zZ])\1\1"

Upvotes: 3

ShAkKiR
ShAkKiR

Reputation: 929

Try this for the first question.

returns true if it finds 3 consecutive numbers or alphabets in the arg

function check(val){
    for (i = 0; i <= val.length - 3; i++) {
      var s1 = val.charCodeAt(i);
      var s2 = val.charCodeAt(i + 1);
      var s3 = val.charCodeAt(i + 2);
      if (Math.abs(s1 - s2) === 1 && s1 - s2 === s2 - s3) {
        return true;
      }
    }

    return false;
}

console.log(check('Sh1ak@ki1r@100'));

Upvotes: -2

D.C.B
D.C.B

Reputation: 1

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.

Upvotes: 0

kuhr
kuhr

Reputation: 602

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))

Upvotes: 0

JNunez247
JNunez247

Reputation: 133

All put together:

([a-zA-Z0-9])\1\1+|(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)+

3 or more consecutive sequential characters/numbers; e.g. 123, abc, 789, pqr, etc.

(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)+

3 or more consecutive identical characters/numbers; e.g. 111, aaa, bbb, 222, etc.

([a-zA-Z0-9])\1\1+

https://regexr.com/4727n

This also works:

(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){2,}\d|(?: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)){2,}[[:alpha:]])|([a-zA-Z0-9])\1\1+

https://regex101.com/r/6fXC9u/1

Upvotes: 1

JNunez247
JNunez247

Reputation: 133

All put together:

([a-zA-Z0-9])\1\1+|(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)+

3 or more consecutive sequential characters/numbers; e.g. 123, abc, 789, pqr, etc.

(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)+

3 or more consecutive identical characters/numbers; e.g. 111, aaa, bbb, 222, etc.

([a-zA-Z0-9])\1\1+

https://regexr.com/4727n

Upvotes: 0

Rosberg Linhares
Rosberg Linhares

Reputation: 3687

  • 3 or more consecutive sequential characters/numbers; e.g. 123, abc, 789, pqr, etc.

    (?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){2,}\d|(?: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)){2,}[\p{Alpha}])
    

    https://regex101.com/r/5IragF/1

  • 3 or more consecutive identical characters/numbers; e.g. 111, aaa, bbb, 222, etc.

    ([\p{Alnum}])\1{2,}
    

    https://regex101.com/r/VEHoI9/1

Upvotes: 0

Mathijs Segers
Mathijs Segers

Reputation: 6238

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;
                }
            }
        }

Upvotes: 0

Adrien NGUYEN
Adrien NGUYEN

Reputation: 299

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

Upvotes: 18

sandy0093
sandy0093

Reputation: 577

Thanks All for helping me.

For the first case - 3 or more consecutive sequential characters/numbers; e.g. 123, abc, 789, pqr, etc. I used below code logic. Pls share your comments on this.

public static boolean validateConsecutiveSeq(String epin) {
    char epinCharArray[] = epin.toCharArray();
    int asciiCode = 0;
    boolean isConSeq = false;
    int previousAsciiCode = 0;
    int numSeqcount = 0;

    for (int i = 0; i < epinCharArray.length; i++) {
        asciiCode = epinCharArray[i];
        if ((previousAsciiCode + 1) == asciiCode) {
            numSeqcount++;
            if (numSeqcount >= 2) {
                isConSeq = true;
                break;
            }
        } else {
            numSeqcount = 0;
        }
        previousAsciiCode = asciiCode;
    }
    return isConSeq;
}

Upvotes: 3

Prashant Bhate
Prashant Bhate

Reputation: 11087

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

Upvotes: 1

Go Dan
Go Dan

Reputation: 15512

3 or more consecutive sequential characters/numbers ex - 123, abc, 789, pqr etc.

Not possible with regular expressions.

3 or more consecutive identical characters/numbers ex - 111, aaa, bbb. 222 etc.

Use a pattern of (?i)(?:([a-z0-9])\\1{2,})*.

If you want to check the whole string, use Matcher.matches(). To find matches within a string, use Matcher.find().

Here's some sample code:

final String ps = "(?i)(?:([a-z0-9])\\1{2,})*";
final String psLong =
        "(?i)\t\t\t# Case insensitive flag\n"
                + "(?:\t\t\t\t# Begin non-capturing group\n"
                + " (\t\t\t\t# Begin capturing group\n"
                + "  [a-z0-9]\t\t# Match an alpha or digit character\n"
                + " )\t\t\t\t# End capturing group\n"
                + " \\1\t\t\t\t# Back-reference first capturing group\n"
                + " {2,}\t\t\t# Match previous atom 2 or more times\n"
                + ")\t\t\t\t# End non-capturing group\n"
                + "*\t\t\t\t# Match previous atom zero or more characters\n";
System.out.println("***** PATTERN *****\n" + ps + "\n" + psLong
        + "\n");
final Pattern p = Pattern.compile(ps);
for (final String s : new String[] {"aa", "11", "aaa", "111",
        "aaaaaaaaa", "111111111", "aaa111bbb222ccc333",
        "aaaaaa111111bbb222"})
{
    final Matcher m = p.matcher(s);
    if (m.matches()) {
        System.out.println("Success: " + s);
    } else {
        System.out.println("Fail: " + s);
    }
}

And the output is:

***** PATTERN *****
(?i)(?:([a-z0-9])\1{2,})*
(?i)            # Case insensitive flag
(?:             # Begin non-capturing group
 (              # Begin capturing group
  [a-z0-9]      # Match an alpha or digit character
 )              # End capturing group
 \1             # Back-reference first capturing group
 {2,}           # Match previous atom 2 or more times
)               # End non-capturing group
*               # Match previous atom zero or more characters


Fail: aa
Fail: 11
Success: aaa
Success: 111
Success: aaaaaaaaa
Success: 111111111
Success: aaa111bbb222ccc333
Success: aaaaaa111111bbb222

Upvotes: 4

pemistahl
pemistahl

Reputation: 9584

To my knowledge, the first case is indeed not possible. The regex engine doesn't know anything about the order of the natural numbers or the alphabet. But it's at least possible to differentiate between 3 or more numbers and 3 or more letters, for example:

[a-z]{3,}|[A-Z]{3,}|\d{3,}

This matches abcd, ABCDE or 123 but doesn't match ab2d, A5c4 or 12z, for example. According to this, the second case can be correctly given in a shorter version as:

  (\w)\1{2,}

Upvotes: 11

Toto
Toto

Reputation: 91508

for the second question:

\\b([a-zA-Z0-9])\\1\\1+\\b

explanation:

\\b               : zero-length word boundary
  (               : start capture group 1
    [a-zA-Z0-9]   : a letter or a digit
  )               : end group
  \\1             : same character as group 1
  \\1+            : same character as group 1 one or more times
\\b               : zero-length word boundary

Upvotes: 12

Related Questions