I don't know how I went this long without discovering named groups in regular expressions, but I'm genuinely excited about them (yes, I'm a nerd).
A quick recap of the most common way to use regular expressions in PowerShell. Let's say I have a string like the one below (sorry it isn't a more simple example, but this is literally something I ran into today). I got it by querying the local administrators of a system using SCCM. The problem is, I want it in domain\user format.
\\SERVER\root\cimv2:Win32_Group.Domain="MYDOMAIN",Name="adminuser"
My first thought was to do something like this:
$string -match '(?<=domain\=")([^"]+).*(?<=name\=")([^"]+)'
It evaluates to True on my test string, so I go look at $matches:
$matches
Name Value
---- -----
2 adminuser
1 MYDOMAIN
0 MYDOMAIN",Name="adminuser
Okay, I've captured my groups, but I notice something strange. Why is $matches a hashtable instead of an array? Because of named groups, that's why.
To create a named group, you put the parentheses around it just like normal, but you add
'?<groupname>' to the beginning of the capture. This stores the group under the name 'groupname'. Let's try that with the above example:
$string -match '(?<=domain\=")(?<domain>[^"]+).*(?<=name\=")(?<name>[^"]+)'
$matches
Name Value
---- -----
name adminuser
domain MYDOMAIN
0 MYDOMAIN",Name="adminuser
It makes my regex a little longer, but it is so much easier now when I go to use the values I've collected to remember $matches.domain and $matches.name instead of $matches[1] and $matches[2].
3 comments:
What version powershell are you using? This does not work with powershell 3.0
Thanks! That's the exact problem I'm trying to solve.
I could not find this answer for referencing the Matches names anywhere else. You saved me.
Post a Comment