Is there an elegant one-liner for doing the following?
$myMatch = \"^abc(.*)\"
$foo -match $myMatch
$myVar = $matches[1]
I\'m interested in
Just use -replace
:
$foo = 'abcDEF'
$myMatch = "^abc(.*)"
$myVar = $foo -replace $myMatch,'$1'
#$myVar contains DEF
Wrap it in a function.
This is almost always the correct answer if you are already happy with and understand a working solution but need it to be shorter. If the function is named properly it also begins to produce self-documenting and re-usable code. What could possibly be better?
Even if you are sure that there is a more elegant or efficient solution out there to find - you can still make it a function call first and then if the other solution comes along, you only have to change it in one place - the function definition itself. You can even then plug in and out different options to test reliability head to head for all of your use cases. What could possibly be better?
Others may complain about function call overhead but this is really neither the right stage of development nor the right type or programming language to worry about it. Debugging a failed attempt at a "cute" one-liner down the road will always outweigh the cost of a nice, clean function call. Good decisions now about clean function call API's can later turn functions into class methods and the classes themselves can seamlessly wrap high level caching and optimization techniques. Lower level optimization of function calls should be left to the lower level languages.
I am not sure about the elegance, but here is something useful:
PS > "123.134" -match "(?<P1>[0-9]{3})\.(?<P2>[0-9]{3})"
True
PS > $Matches
Name Value
---- -----
P2 134
P1 123
0 123.134
PS > $Matches["P1"]
123
?<P1>
gives the label P1
to the first capture. It helps to understand.
PS > ([regex]("(?<P1>[0-9]{3})\.(?<P2>[0-9]{3})")).matches("123.123")[0].groups["P1"].value
123
In your case:
PS > $foo = "123.143"
PS > ([regex]("(?<P1>[0-9]{3})\.(?<P2>[0-9]{3})")).matches($foo)[0].groups["P1"].value
123
PS > ([regex]("(?<P1>[0-9]{3})\.(?<P2>[0-9]{3})")).matches($foo)[0].groups["P2"].value
143
I use something like the following pretty often:
([regex]"^abc(.*)").match($foo).groups[1].value
It's not very PowerShell-y, or at least not very PowerShell V2-y (we're falling back onto the .NET class)... but it's pretty compact.
Changed answer after clarification:
True one-liner:
$myvar = ($foo | ? {$_ -match $myMatch} | select @{L="Matches";E={$matches[1]}}).matches
Fake one-liner:
$foo | ? {$_ -match $myMatch} ; $myvar = $matches[1]