Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the PowerShell syntax to capture a named group from a [regex] type accelerator expression?

The question uses the following sample string:

$r = 
"20160112 11:26:39 UPDATE CMIS-NC.ABC.LA012345J.NAM/MOUSE, MICKEY J.SEX/M.RAC/W.DOB/19670601.PCA/A1.ARI/CRIM1234567.DNY/CONVICTED OF DISTRIBUTING THE PEACE.OCA/123456.SOR/LA.MIS/CONFIRM RECORD AT DISNEY STUDIOS 123-456-7890 OR PAGER 123-456-7890.
20160112 11:26:39 RESPONSE CMIS-NC.ACK 1234567890 CMIS-NC  123456 CMIS-NC  123456 20160112 11:26:31

.
20160112 11:26:39 INFO MSN of message to LEMS is <1234567890>.
20160112 11:26:39 RESPONSE CMIS-NC.MSG 1234567890 CMIS-NC  123456 NC2K     AC1234 20160112 11:26:31
LA012345J
CTL/
ATN/

6L12345678901234567890EDP 
LA012345J
ACCEPT MKE/EDP
NAM//MOUSE, MICKEY J
ARI/CRIM1234567
NRI/1234567890"

A named group can be captured using the PowerShell built-in regular expression, by referencing them in the $matches automatic variable:

$updateRequestPattern = "(?<RequestDate>\d{8} \d{2}:\d{2}:\d{2}) (?<UpdateRequest>UPDATE CMIS-NC\.[A-Z]{3,4}\.LA012345J\..+)\n"

$request = $r -match $updateRequestPattern

$matches['RequestDate']

But what if I instead want to use the [regex] type accelerator?

There, the $matches automatic variable won't work. Neither can I do something like [regex]::Groups['RequestDate'].Value (which produces a "Cannot index into a null array." error).

Can anyone complete this example (or offer another example) to capture named groups (and thus show how other .NET [regex] methods can be exposed)?

$updateRequestPattern = "(?<RequestDate>\d{8} \d{2}:\d{2}:\d{2}) (?<UpdateRequest>UPDATE CMIS-NC\.[A-Z]{3,4}\.LA036035J\..+)\n"
$request = [regex]::Matches($r, $updateRequestPattern)
like image 312
504more Avatar asked May 20 '16 20:05

504more


2 Answers

The return value is a MatchCollection, so you can index into that, then refer to the groups property, and use the indexing the same way from there:

$request[0].Groups['RequestDate']
like image 159
briantist Avatar answered Nov 12 '22 22:11

briantist


I'm not seeing that the pattern doesn't match (it matches in Regex101.com, and it matched in the first example that I provided).

But following your suggestion, and simplifying even further, then, this works as you recommended.

$s = "ABC123"
$p = "(?<LetterPart>[A-Z]+)(?<NumberPart>\d+)"
$result = [regex]::Matches($s, $p)

$result[0].Groups['LetterPart'].Value
$result[0].Groups['NumberPart'].Value

Thank you!

like image 41
504more Avatar answered Nov 12 '22 21:11

504more