0

I'm doing a project in C# that includes table and user management. In my custom control TextBox I need to validate whether the user introduces a valid Spanish DNI or not. The DNI format is 8 numbers and 1 letter. The method has to unable writing if the user types more than 8 numbers or more than one letter in this order (12345678A). If someone could help i would be very grateful! Thanks for reading.

I have tried this Regular Expressions method but it doesn't work.

private void ValidateText(object sender, KeyPressEventArgs e)
{
   string pattern = @"^((\d{8})|(\d{8}([A-Z]|[a-z])))$";

   Regex r = new Regex(pattern);

   if ((r.IsMatch(this.Text)))
   {
       e.Handled = true;
   }
}
  • Does this answer your question? [Reference - What does this regex mean?](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean) – gunr2171 Nov 11 '19 at 19:17
  • After the edit, the regex now checks if the string is 8 digits, or 8 digits followed by a letter in the A-Z range, but not, say, Ñ, and includes K and W, which aren't in the natural Spanish alphabet (although included in many because of loan words). – Heretic Monkey Nov 11 '19 at 20:36

3 Answers3

0

You don't need to use a regex for such a simple rule. Use this method below

public static bool ValidateSpanishDNI(string value)
{
    if(value == null) return false;
    if(value.Length != 9) return false;
    if(char.IsLetter(value[8]) == false) return false;
    for(int i = 0; i < 8; i++) {
        if(char.IsDigit(value[i]) == false)
            return false;

    }

    return true;
}
Mihail Shishkov
  • 9,449
  • 5
  • 40
  • 54
0

Here is an alternative solution using Linq.

string value = this.Text;
int outInt = 0;

int numbersCount = value.Count(c => Char.IsNumber(c));
e.Handled = ( (numbersCount == 8) && 
              (value.Length - numbersCount == 1) &&
             !(int.TryParse(value[value.Length - 1].ToString(), out outInt))
             );
Koga
  • 722
  • 5
  • 15
0

What about your regular expression does not work? I used your exact regular expression in dotnetfiddle and it seems to work just fine.

There are a couple things to note:

  • This regex will work for both 12345678A and A12345678. Is that your intention?
  • You don't need to do [A-Z]|[a-z]. You may simply use [A-Za-z] and it will work (as shown below.

string pattern = @"^((([A-Za-z])\d{8})|(\d{8}([A-Za-z])))$";

Please see this example derived from your code as reference and let me know if you have any questions!

https://dotnetfiddle.net/pK1Hny

user1477388
  • 19,139
  • 26
  • 125
  • 240