tags:

views:

383

answers:

5
  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
A: 

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.

Robert P
+1  A: 

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

Konrad Rudolph
+2  A: 

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";
}
in this case "a/5" validates...
streetpc
I don't see anything in the question that would imply that other characters shouldn't validate
max should be 4 letters and max 2 digits i.e letters<=4 and digits<=2
ok, well that's easy to fix - updated my answer - instead of looking at .{0,6} i now look at [a-z0-9]{0,6}@kurozakura - you may want to consider adding to the question that only letters and digits are allowed in the total count of 6.
+1  A: 

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
streetpc
A: 

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}

Jon Galloway