## Tuesday, January 24, 2012

### Named Groups in Regular Expressions

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.

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
----                           -----
1                              MYDOMAIN

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
----                           -----
domain                         MYDOMAIN

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