kurozakura
kurozakura

Reputation: 2349

Regex to validate at most 2 numbers and at most 4 alphabets in an string of length 6

  1. Max Length of the String is 6.
  2. The string should contain at most 2 digits
  3. The string should contain at most 4 alphabets

So the following examples should match

abcd22

a1cd3d

11acde

a1c

1ad

Upvotes: 4

Views: 8336

Answers (5)

naumcho
naumcho

Reputation: 19891

I'd do an OR test of a bunch of regexes:

/^[a-z0-9]{0,6}$/ # at most 6 characters
/([a-z].*){5}/    # more than 4 letters
/(\d.*){3}/       # more than 2 digits

So:

if ( /^[a-z0-9]{0,6}$/ and !( /([a-z].*){5}/ or /(\d.*){3}/ ) ) {
  print "valid";
}

Upvotes: 2

Jon Galloway
Jon Galloway

Reputation: 53115

You could do this using negative lookaheads.

(?!\d{5})(?![a-z]{3})[a-z0-9]{1,6}

(?!\d{5}) fails if 5 or more digits are found

(?![a-z]{3}) fails if 3 or more characters are found

If both of those pass, we finally verify that there are between 1 and 6 alphanumeric characters with (?!\d{5})(?![a-z]{3})[a-z0-9]{1,6}

Upvotes: 0

instanceof me
instanceof me

Reputation: 39138

I would not use regex for this one, except maybe to check for alphanumeric/less than 6: /^[0-9a-z]{1,6}$/i. But the count conditions, while technically doable using regexes, are done better with simple counting.

So i would

  1. Test if it matches regex /^[0-9a-z]{1,6}$/i
  2. Then use a for loop to count chararcter classe occurences

Upvotes: 1

Konrad Rudolph
Konrad Rudolph

Reputation: 545538

What you want isn’t really possible in regular expressions because regular expressions can’t count, which would be required here. In fact, regular expressions seem to be able to count characters in direct sequence, e.g. in this case:

/x{2,3}/ # 2 or 3 ‘x’s

… but that’s actually not counting, because it’s just a shortcut for this expression:

/xxx?/

i.e. 2 x’s, followed by an optional third one.

Your expression, on the other hand, would have to keep track of two different counters over the whole automaton which represents the expression. That’s simply not possible in classical regular expressions (and still very hard using more modern incarnations of regular expressions which use pushdown automata to save states).

Upvotes: 2

Robert P
Robert P

Reputation: 15968

Regexes are not good at keeping track of state. You could do this with a regex, but it would be much easier to use a simple calculator and small regexes program:

bool IsValid(string s)
{
   int numInts = 0;
   int numChars = 0;
   Regex isDigit = new Regex(@"\d");
   Regex isChar  = new Regex(@"[a-zA-Z]"); // NOTE: will NOT catch non english letters

   if (s.Length() <= 6) 
   {
       return false;
   }

   foreach (char c in s)
   {
       if (isDigit.IsMatch(c)) 
       {
           ++numInts;
       }
       if (isChar.IsMatch(c))
       {
           ++numChars;
       }
   }

   return numInts == 2 && numChars == 4;

}

Constify / rename args to meet your needs.

Of course, if you want to be very C like, you could do a numeric comparison on the char, but that will even further take you away from a solid, robust solution.

Upvotes: 0

Related Questions