Search code examples
regexpowershellpowershell-3.0

Powershell Regex confusion


Target String:

8AM - 10AM (local time)
12PM - 1PM (local time)

I am able to extract the times from https://regexr.com/ with this expression:

\d{1,2}(AM|PM)

However,i am not able to do so in powershell:

cls
$var = "8AM - 10AM (local time)
12PM - 1PM (local time)"
if ($var -match "\d{1,2}(AM|PM)")
{
    $matches
}

PS output:

Name    Value                                                                                                                                                                                                            
----    -----                                                                                                                                                                                                            
1       AM                                                                                                                                                                                                               
0       8AM       

However, when I use the script below in PS:

cls
$var = "8AM - 10AM (local time)"
[regex]::Matches($var,"\d{1,2}(AM|PM)").Value

It gives the correct output:

8AM
10AM

Any ideas as to why this is happening?


Solution

    • The -match operator only ever looks for at most 1 match.

      • [regex]::Matches() is indeed the right choice if you need multiple matches.
      • Alternatively, use the Select-String cmdlet, which will be much slower, however:
        ('8AM - 10AM (local time)' | Select-String -AllMatches '\d{1,2}(AM|PM)').Matches.Value
    • Thus, with -match, the automatic $Matches results variable only ever contains information about that 1 match, possibly including capture-group matches.

      • The (AM|PM) part of your regex is a capture group, so for the 1st overall match - 8AM - that capture group's result is AM.
      • $Matches is a [hashtable] whose entry with the 0 key contains the overall match; entry <n> contains the nth (unnamed) capture-group result.
      • Since enumeration of the entries of a [hashtable] happens in no guaranteed order, the 1 entry happens to be listed before the 0 entry in this case.