Search code examples
powershellobjectmatchassign

Accessing matches variables in Powershell


This question is more about my understanding Powershell's objects rather than solving this practical example. I know there are other ways of separating out a page number from a string.

In my example I want to do this by accessing the object-match-value of the piped pattern match.

# data
$headerString = 'BARTLETT-BEDGGOOD__PAGE_5 BEECH-BEST__PAGE_6'
# require the number of page only
$regexPageNum = '([0-9]$)'

# split the header string into two separate strings to access page numbers
[string[]]$pages = $null
$pages = $headerString -split ' '

# access page numbers using regex pattern 
$pages[0] | Select-String -AllMatches -Pattern $regexPageNum | Select-Object {$_.Matches.Value}

The output is:

$_.Matches.Value
----------------
5

Okay. So far so good. I see the page number of array member pages[0] But how do I take this value from the object? The following does not work.

$x = $pages[0] | Select-String -AllMatches -Pattern $regexPageNum | Select-Object {$_.Matches.Value}
Write-Host "Here it is:"$x

Output:

Here it is: @{$_.Matches.Value=5}

Instead of assigning the value 5 to the variable $x Powershell assigns, what looks to me: a hash table with an object description as its only member?

But if I try to access my variable using "Brackets for Access" Reference: hashtables Powershell indicates that variable $x is in fact an array.

x = $pages[0] | Select-String -AllMatches -Pattern $regexPageNum | Select-Object {$_.Matches.Value}
Write-Host "Here it is:"$x
$y = $x[$_.Matches.Value]
Write-Host "What about now:"$y

Output:

Here it is: @{$_.Matches.Value=5}
InvalidOperation: 

Line |
  33 |  $y = $x[$_.Matches.Value]
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~
     | Index operation failed; the array index evaluated to null.

What about now:

Okay. At this stage I know I'm being silly. But the point I'm trying to make is: How can I retrieve the value I want when I'm done with the Powershell object?


Solution

  • You can use $x.{ $_.Matches.Value } to access the value.

    $x = $pages[0] | Select-String -AllMatches -Pattern $regexPageNum | Select-Object { $_.Matches.Value }
    $x.{ $_.Matches.Value } # This will print 5
    

    ie, You would have to wrap the property name inside {} since the property name contains "."

    Instead of this way, I would suggest you to create a calculated property using Select-Object which makes the code more readable.

    $x = $pages[0] | Select-String -AllMatches -Pattern $regexPageNum | Select-Object @{Name = 'PageNumber'; Expression = {$_.Matches.Value}}
    $x.PageNumber