123testing123
123testing123

Reputation: 77

How do I capture the 2nd match for each line?

Basically, I need to match with 1 per line but right now, my regex is matching 2 per line.

https://regex101.com/r/KmgGwS/8

My regex is looking for 2 slashes and it returns the string in between but the problem is my path has multiple slashes and I only need to match it with the 2nd match per each line

(?<=\\).*?(?=\\)

This is my PowerShell code:

if ( $_.PSPath -match ("(?<=::).*?(?=\\)")) {
    $user = $matches.Values
}

For example:

Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\CDD4EEAE6000AC7F40C3802C171E30148030C072
Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\BE36A4562FB2EE05DBB3D32323ADF445084ED656

What my code does is it gets

Certificate::CurrentUserRoot
Certificate::CurrentUserRoot

but what I only really need is get the string to the 2nd match \ ___\ which is:

Root
Root

Upvotes: 1

Views: 292

Answers (3)

mklement0
mklement0

Reputation: 439587

To offer a pragmatic alternative using PowerShell's -split operator:

PS> 'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\CDD4EEAE6000AC7F40C3802C171E30148030C072',
'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\BE36A4562FB2EE05DBB3D32323ADF445084ED656' |
  ForEach-Object { ($_  -split '[::|\\]')[4] }

Root
Root

The above tokenizes each input string by separators \ or ::, and extracts the 4th token.

Upvotes: 0

The fourth bird
The fourth bird

Reputation: 163477

You could make use of an anchor ^ to assert the start of the string. Repeat 2 times matching not a backslash or a newline followed by a backslash.

Use a capturing group to match what follows;

^[^\\\r\n]*\\[^\\\r\n]*\\([^\\\r\n]+)

About the pattern

  • ^ Start of string
  • [^\\\r\n]*\\[^\\\r\n]*\\ Match 2 times not \ or a newline, then \
  • ( Capture group 1
    • [^\\\r\n]+ Match 1+ times not \ or a newline
  • ) Close group 1

Regex demo | Try it online

The value is in the first capturing group:

$user = $matches[1]

If you want the match only to use your script instead of group 1, you could make use of a positive lookbehind to assert what is on the left is 2 times not \ followed by \

(?<=^[^\\\r\n]*\\[^\\\r\n]*\\)[^\\\r\n]+

Regex demo | Try it online

Upvotes: 1

Emma
Emma

Reputation: 27743

I'm guessing that, maybe an expression similar to,

(?<=\\)[^\\]*(?=\\[A-Z0-9]{40}$)

might be an option to look into.

Demo 1

Or maybe just,

[^\\]*(?=\\[A-Z0-9]{40}$)

or

[^\\]*(?=\\[A-F0-9]{40}$)

would simply return Root and 40 is the length of [A-F0-9] ending substring. For more flexible quantifier, this expression might work:

[^\\]*(?=\\[A-F0-9]*$)

Demo 2

Upvotes: 1

Related Questions