1

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
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
123testing123
  • 57
  • 2
  • 10

3 Answers3

1

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

Emma
  • 27,428
  • 11
  • 44
  • 69
1

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

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

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.

mklement0
  • 382,024
  • 64
  • 607
  • 775