CodeNagi
CodeNagi

Reputation: 419

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?

Upvotes: 3

Views: 193

Answers (1)

mklement0
mklement0

Reputation: 438153

  • 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.

Upvotes: 4

Related Questions