18

In PowerShell I find myself doing this kind of thing over and over again for matches:

some-command | select-string '^(//[^#]*)' |
     %{some-other-command $_.matches[0].groups[1].value}

So basically - run a command that generates lines of text, and for each line I want to run a command on a regex capture inside the line (if it matches). Seems really simple. The above works, but is there a shorter way to pull out those regex capture groups? Perl had $1 and so on, if I remember right. Posh has to have something similar, right? I've seen "$matches" references on SO but can't figure out what makes that get set.

I'm very new to PowerShell btw, just started learning.

scobi
  • 14,252
  • 13
  • 80
  • 114

3 Answers3

15

You can use the -match operator to reformulate your command as:

some-command | Foreach-Object { if($_ -match '^(//[^#]*)') { some-other-command $($matches[1])}}
Steven Murawski
  • 10,959
  • 41
  • 53
Bas Bossink
  • 9,388
  • 4
  • 41
  • 53
  • Eh? He's matching a line that starts with double-slash (//) and greedily matching up until (but excluding) the first hash (#). There is no end-of-line marker, so he's not specifically matching the entire line. – Peter Boughton Jun 18 '09 at 07:22
  • Yeah, that's the kind of thing I was looking for. Thanks for the edit, Bas. – scobi Jun 18 '09 at 15:35
8

Named Replacement

'foo bar' -replace '(?<First>foo).+', '${First}'

Returns: foo

Unnamed Replacement

 'foo bar' -replace '(foo).+(ar)', '$2 z$2 $1'

Returns: ar zar foo

Joe
  • 81
  • 1
  • 1
4

You could try this:

Get-Content foo.txt | foreach { some-othercommand [regex]::match($_,'^(//[^#]*)').value } 
Steven Murawski
  • 10,959
  • 41
  • 53
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • For me this outputs a blank line if the input doesn't match. [Bas Bossink](http://stackoverflow.com/a/1011163/111424)'s answer works like this one but outputs only the matches. – Iain Samuel McLean Elder May 26 '14 at 20:18