Search code examples
regexpowershellcomparison-operators

Why does Powershell string match escaped regex return false but still output correct match?


The code below works as is. The commented out lines are the alternative version which does not work.

[string]$secretString = "Secret message: The agent
was a man called Bond
007 BOND, James MI5 London
....... end"

# [string]$agent = '007 BOND'   # [regex]::Escape($agent)
[string]$result = $null

$secretString -match "(007 BOND[^\r\n]*)"
# $secretString -match "([regex]::Escape($agent)[^\r\n]*)"
$result = $Matches[0]

Write-Host "The full name of agent is: $result"

The output for working version is:

True
The full name of agent is: 007 BOND, James MI5 London

The output for non-working version (uncomment $agent declaration & swap $secretString -match line from explicit to escaped) is:

False
The full name of agent is: 007 BOND, James MI5 London

How can this happen? As I understand from Matching operators the $Matches automatic variable should be overwritten.

As it happens. If I open a new terminal in VS, to run the errant code again, I now get:

False
InvalidOperation:
    15 |  $result = $Matches[0]
         |  ~~~~~~~~~~~~~~~~~~~~~
         | Cannot index into a null array.

The messaging & logic is now consistent. This means I have two problems.

  1. What is wrong with my regex escape code?
  2. Why is the $Matches automatic variable not being overwritten? On the second run of the code it should be overwritten to null because the comparison operator match returns a false match.

Any suggestions would be appreciated.


Solution

  • As for the second point, check the note section here regarding matches:

    When $Matches is populated in a session, it retains the matched value until it's overwritten by another match. If -match is used again and no match is found, it doesn't reset $Matches to $null. The previously matched value is kept in $Matches until another match is found.