Powershell regex how to verify that no specific characters exist or otherwise there are no characters

Jairo Javier Baleta Cali 286 Reputation points
2023-09-25T22:35:06.36+00:00

Good afternoon.

I hope you are well.

I am trying to verify through a regular expression that there are no specific characters or if not, it does not have any characters. For example, I have the date formats "MM/dd/yyyy", "MM-dd-yyyy", and "MMddyyyy". I need an expression that validates that between "MM" and "dd" only the characters "/", "-" exist or otherwise it does not have any characters. In the same way between "MM" and "yyyy".

I hope you can help me.

Thank you so much.

Windows for business Windows Server User experience PowerShell
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 47,901 Reputation points
    2023-09-26T15:44:33.01+00:00

    Are you sure you're understanding the requirements? What you say "they" want is straightforward character matching (with case-sensitivity):

    "MM/dd/yyyy" -cmatch "(MM/dd/yyyy)|(MM-dd-yyyy)|(MMddyyyy)"
    "MM-dd-yyyy" -cmatch "(MM/dd/yyyy)|(MM-dd-yyyy)|(MMddyyyy)"
    "MMddyyyy"   -cmatch "(MM/dd/yyyy)|(MM-dd-yyyy)|(MMddyyyy)"
    

    But you don't even need to use regular expressions to accomplish that! Simple string comparisons work, too:

    "MM/dd/yyyy" -ceq "MM/dd/yyyy"
    

    Is this some sort of homework assignment?

    If you're really being asked to verify dates to adhere to certain formats with some basic content verification, you can use this:

    # regex matches MM-dd-yyyy or MM/dd/yyyy
    "
    ^                           # beginning of string
    (1[0-2]|[1-9])              # month 10,11, or 12 -- or 01-09
    (/|-)                      # separator "/" or "-"
    (3[01]|[12][0-9]|0?[1-9])   # day
    \2                          # the 1st separator (a backreference)
    ([0-9]{4})                  # year (4 digits)
    $                           # end of string
    "
    "12/30/2023" -match "^(1[0-2]|0?[1-9])(/|-)(3[01]|[12][0-9]|0?[1-9])\2([0-9]{4})$"     # TRUE
    "12-30-2023" -match "^(1[0-2]|0?[1-9])(/|-)(3[01]|[12][0-9]|0?[1-9])\2([0-9]{4})$"     # TRUE
    "12302023"   -match "^(1[0-2]|0?[1-9])(3[01]|[12][0-9]|0?[1-9])([0-9]{4})$"            # TRUE (NOTE: Uses a different regex without accounting for separators, so there's no backreference either
    "13/30/2023" -match "^(1[0-2]|0?[1-9])(/|-)(3[01]|[12][0-9]|0?[1-9])\2([0-9]{4})$"     # FALSE (month is incorrect)
    
    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Anonymous
    2023-09-26T02:04:39.7766667+00:00

    Hi,

    Please see if this meets your needs.

    '\d{2}[/-]?\d{2}[/-]?\d{4}'
    

    Best Regards,

    Ian Xue


    If the Answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Rich Matheisen 47,901 Reputation points
    2023-09-26T02:53:59.11+00:00

    Dates really aren't as simple they seem (and time is even more complicated!). Writing a regex is pretty easy if it's just to check the format, but it gets harder when you want to actually verify that the date is correct.

    For example, 09/31/2023 will pass a simple format test, but it isn't a real date.

    The code below uses the .Net DateTime class to verify the format and validity of the date string (including the leap year problem with that extra day in February!).

    $dates = "12202023","12/21/2023", "12-22-2023",'12.23.2023'
    $dateformats = "MM/dd/yyyy","MM-dd-yyyy","MMddyyyy"
    $provider = [System.Globalization.CultureInfo]::InvariantCulture
    
    
    ForEach ($date in $dates){
        $okdate = $false
        ForEach ($format in $dateformats){
            $d = $date          # just for demo purposes
            $f = $format        # just for demo purposes
            try{
                $x = [DateTime]::ParseExact($date,$format,$provider)
                $okdate = $true
                break
            }
            Catch{
                # no need to do anything here, just suppress the error message
            }
        }
        # all the rest is just to show the results, in production this isn't necessary
        if ($okdate){
            "Date $d OK ($f)"
        }
        else{
            "Date $d BAD (all tested formats)"
        }
    }
    
    

    Running that code gives these results:

    Date 12202023 OK (MMddyyyy)
    Date 12/21/2023 OK (MM/dd/yyyy)
    Date 12-22-2023 OK (MM-dd-yyyy)
    Date 12.23.2023 BAD (all tested formats)
    Date 09/31/2023 BAD (all tested formats)
    

    In the example code the "$x" variable isn't used, but you can use that to further test the converted date for things such as the year being within the range of, say, 1950 and 2023. You can find errors in the year that are mistakes, such as the value being beyond the current year in the result of a "Get-Date".

    0 comments No comments

  3. Jairo Javier Baleta Cali 286 Reputation points
    2023-09-26T12:39:06.31+00:00

    Good morning.

    Thank you very much for the answers.

    What I'm trying to evaluate with the regular expression is directly the date format ("MM/dd/yyyy", "MM-dd-yyyy", and "MMddyyyy"). With the examples they sent me I tried the following and it didn't work:

    I show you the tests I have carried out:

    Using the "[/-_]" separator:

    "mmddyyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_](m{1,2}|d{1,2}| y{1,4})[/\-_](m{1,2}|d{1,2}|y{1,4}))"
    False -> must be True
    
    "mm/dd/yyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_](m{1,2}|d{1 ,2}|y{1,4})[/\-_](m{1,2}|d{1,2}|y{1,4}))"
    True -> OK
    
    "mm-dd-yyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_](m{1,2}|d{1 ,2}|y{1,4})[/\-_](m{1,2}|d{1,2}|y{1,4}))"
    True -> OK
    
    "mm(dd)yyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_](m{1,2}|d{1 ,2}|y{1,4})[/\-_](m{1,2}|d{1,2}|y{1,4}))"
    False -> OK
    
    

    Using the "[/-_]?" separator:

    "mmddyyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_]?(m{1,2}|d{1,2} |y{1,4})[/\-_]?(m{1,2}|d{1,2}|y{1,4}))"
    True -> OK
    
    "mm/dd/yyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_]?(m{1,2}|d{ 1,2}|y{1,4})[/\-_]?(m{1,2}|d{1,2}|y{1,4}))"
    True -> OK
    
    "mm-dd-yyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_]?(m{1,2}|d{ 1,2}|y{1,4})[/\-_]?(m{1,2}|d{1,2}|y{1,4}))"
    True -> OK
    
    "mm(dd)yyyy" -match "((m{1,2}|d{1,2}|y{1,4})[/\-_]?(m{1,2}|d{ 1,2}|y{1,4})[/\-_]?(m{1,2}|d{1,2}|y{1,4}))"
    True -> must be False
    
    

    I hope you can help me.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.