简体   繁体   中英

how to write regular expression to validate a string using regex in C#

I need to validate a user input based on condition. i wrote a regular expression to do so, but it's failing not sure why. Can somebody point where i am making mistake?

Regex AccuracyCodeHexRegex = new Regex(@"^[PTQA]((0|8)[01234567]){2}$");

This is what i am trying to validate(If the string is a subset of these strings then it is valid):

Phh, Thh, Qhh, Ahh where 'h' is a hex digit in the set {00, 80, 01, 81, 02, 82, 03, 83, 04, 84, 05, 85, 06, 86, 07, 87}

Ex: P00 is valid P20 is not valid

I would write :

^[PTQA]((0|8)[0-7])$

you don't seem to need the {2} which validates strings like P0707

Your Regex ^[PTQA](?:(?:0|8)[01234567]){2}$

Applies to the following :

P8001
P8002
P0281
P8005

and so on, because you are repeating the number matches by {2}

To validate something like P81 / P05, you need to change that to {1}

you can simplify your regex to ^[PTQA](?:(?:0|8)[0-7])$ which will do the trick for you

if you need speed regex aren't terribly fast and usually simple lookups on static values can be implemented with a switch-case. They aren't that nice when it comes to maintainability but if the values are fairly stable and only used in this one place that shouldn't be too much of a concern. If it is you can use a HashSet of all the valid values.

Using a HashSet:

var leading = new[]{'P','T','Q','A'};
var firstDigit = new []{'0','8'};
var lastDigit = new []{'0','1','2','3','4','5','6','7'};

var set = new HashSet<string>(from l in leading
                              from f in firstDigit
                              from lst in lastDigit
                              select l + f + lst);

public bool IsOk(string value){
   return set.Contains(value);
}

or using switch-case:

public bool IsOk(string value){
   if(value.length != 3) return false;
   switch(value[0]){
       case 'P':
       case 'T':
       case 'Q':
       case 'A':
          switch(value[1]){
               case '0':
               case '8':
                   switch(value[2]){
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                            return true;
                   }
         }

   }
   return false;
}

If you sort the possible hex digits in a list you could build the regex automatically like so

var hexs = new List {"00", "80", "01", "81", "02"};
var regex = string.Format("^[PTQA]({0})", string.Join("|", hexs));
var accuracyCodeHexRegex = new Regex(regex);

If the possible values are known, why don't you compare to an array of this known possibles values?

void Foo(){

    var valueToTest1 = "P07";
    var valueToText2 = "Z54";

    TestValue(valueToTest1);
    TestValue(valueToTest1);
}

bool TestValue(string stringToTest)
{
    var hexValues = new string[] { "00", "80", "01", "81", "02", "82", "03", "83", "04", "84", "05", "85", "06", "86", "07", "87"};
    var leftValues = new char[] { 'P', 'Q', 'H' };

    var left = stringToTest[0];
    var right = strintToTest.SubString(1,2);

    return leftValues.Contains(left) && hexValues.Contains(right);
}

This is a lot simpler than using a regex and I believe far more performant

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM