locked
Refactor the Regex match RRS feed

  • Question

  • User-1256377279 posted

    Hi Guys,

    Below is my code to check Regex expression, Please can you improvise so that it reduce the time to validate.

     public bool isDateValid(string date)
            {
                datePattern = date;
    
                result = false;
    
                var IamsDatePatterns = new List<string>();
    
    
                // All other format
                            
              
                IamsDatePatterns.Add("^(\\d{4}|\\d{4}-\\d{4})$");
                //IamsDatePatterns.Add("^\\d{4}-\\d{4}$");
                IamsDatePatterns.Add("^(b|c|d|before|after|fl)\\s\\d{4}$");           
                IamsDatePatterns.Add("^[c]\\s\\d{4}-[c]\\s\\d{4}$");
                IamsDatePatterns.Add("^(c|between|fl)\\s\\d{4}-\\d{4}$");
                IamsDatePatterns.Add("^\\d{4}-[c]\\s\\d{4}$");
                IamsDatePatterns.Add("^(\\d{4}(s|\\?)|\\d{4}(s|\\?)-\\d{4}(s|\\?))$");
                //IamsDatePatterns.Add("^\\d{4}(s|\\?)-\\d{4}(s|\\?)$");
                IamsDatePatterns.Add("^\\d{4}-\\d{4}[s]$");
                IamsDatePatterns.Add("^\\d{4}[s]-\\d{4}$");
                IamsDatePatterns.Add("^(Early|Late|Mid)\\s\\d{4}[s]$");
                //IamsDatePatterns.Add("^\\[\\d{4}[s]-\\d{4}\\]$");
                IamsDatePatterns.Add("^(\\[\\d{4}\\]|\\[\\d{4}[s]-\\d{4}\\])$");
                IamsDatePatterns.Add("^(\\d{2}(st|nd|rd|th)\\s(century)|\\d{2}(st|nd|rd|th)\\s(century)-\\d{2}(st|nd|rd|th)\\s(century))$");
                //IamsDatePatterns.Add("^\\d{2}(st|nd|rd|th)\\s(century)-\\d{2}(st|nd|rd|th)\\s(century)$");
                IamsDatePatterns.Add("^(Early|Mid|Late)\\s\\d{2}(st|nd|rd|th)\\s(century)$");
                IamsDatePatterns.Add("^(\\d{1}(st|nd|rd|th)\\s(half|quarter)\\s(of)\\s(the)\\s\\d{2}(st|nd|rd|th)\\s(century)|\\d{1}(st|nd|rd|th)\\s(half|quarter)\\s(of)\\s(the)\\s\\d{2}(st|nd|rd|th)\\s(century)-\\d{1}(st|nd|rs|th)\\s(half|quarter)\\s(of)\\s(the)\\s\\d{2}(st|nd|rd|th)\\s(century))$");
                //IamsDatePatterns.Add("^\\d{1}(st|nd|rd|th)\\s(half|quarter)\\s(of)\\s(the)\\s\\d{2}(st|nd|rd|th)\\s(century)-\\d{1}(st|nd|rs|th)\\s(half|quarter)\\s(of)\\s(the)\\s\\d{2}(st|nd|rd|th)\\s(century)$");
                IamsDatePatterns.Add("^\\d{2}\\s(BC)$");
                IamsDatePatterns.Add("^\\d{1}(st|nd|rd|th)\\s(century)\\s(BC)$");
                IamsDatePatterns.Add("^\\d{4}(s|\\?|-)$");
                
                //All Date format
                IamsDatePatterns.Add("^\\d{2}\\s[A-Z][a-z][a-z]\\s\\d{4}$"); //dd MMM yyyy
                IamsDatePatterns.Add("^[A-Z][a-z][a-z]\\s\\d{4}$"); //MMM yyyy
                IamsDatePatterns.Add("^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}$"); // dd/MM/YYYY
                IamsDatePatterns.Add("^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}\\s(20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$"); // dd/MM/YYYY HH:MM:SS
                IamsDatePatterns.Add("^([0-9]{4})-([0-1][0-9])-([0-3][0-9])(T|\\s)([0-1][0-9]|[2][0-3]):([0-5][0-9]):([0-5][0-9])$"); // YYYY-MM-DDTHH:MM:SS
    
    
                
    
    
                foreach (string Pattern in IamsDatePatterns)
                {
                    if (Regex.IsMatch(datePattern, Pattern))
                    {
                        result = true;
                        break;
                    }
                }
    
    
                return result;
            }



    Wednesday, March 13, 2019 4:29 PM

All replies

  • User-893317190 posted

    Hi shabbir_215,

    Not sure what you want to do by validating so many formats of date.

     You could reduce the times by ? in regex.

     Such as your following regex  could be combined into  "^(\\d{2}\\s)?[A-Z][a-z][a-z]\\s\\d{4}$" because dd could appear one time or zero.

     IamsDatePatterns.Add("^\\d{2}\\s[A-Z][a-z][a-z]\\s\\d{4}$"); //dd MMM yyyy
                IamsDatePatterns.Add("^[A-Z][a-z][a-z]\\s\\d{4}$"); //MMM yyyy

    And your regex could be combined to "^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}(\\s(20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d)?$" because HH:MM:SS could appear  one time or zero

     IamsDatePatterns.Add("^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}$"); // dd/MM/YYYY
                IamsDatePatterns.Add("^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}\\s(20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$"); // dd/MM/YYYY HH:MM:SS
    

    Your regex  could also be combined , becaue the first part (Early|Late|Mid) is the same.

     IamsDatePatterns.Add("^(Early|Late|Mid)\\s\\d{4}[s]$");
               
                IamsDatePatterns.Add("^(Early|Mid|Late)\\s\\d{2}(st|nd|rd|th)\\s(century)$");

    However, even you could do this, it is not easy to write a right regex for all kinds of  datetime.

    For example a year have 12 months, not all numbers for months are right. And MMM for datetime is Jan , Feb... , not all a-z are right.

    One way is to use DateTime.TryParseExact , it could check the format for you and you don't need to write so much regex.

    Please refer to https://stackoverflow.com/questions/19019718/checking-date-format-from-a-string-in-c-sharp

    And below is the doc for DateTime.TryParseExact https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tryparseexact?view=netframework-4.7.2

    Best regards,

    Ackerly Xu

    Thursday, March 14, 2019 2:22 AM
  • User303363814 posted

    When I test this code it takes between 200 and 300 microseconds to run on my (fairly old) laptop.  What time does it take for you?  What time are you trying to achieve?

    I get that this is not really your code (what you have shown will not compile) but you must have some timing data.

    Monday, March 25, 2019 9:43 PM