Reputation: 144
So, here the example below.
Application Details for the XYZ application:
=========================================================
Application Name: XYXZW1
Application Id: XYZ353WERX
Application Details for the XYZ application:
=========================================================
Application Name: XYXZW2
Application Id: XYZ353WERX
Application Details for the XYZ application:
=========================================================
Application Name: XYXZW3
Application Id: XYZ353WERX
Secret Key: XYZ86JBHHSD
Application Details for the XYZ application:
=========================================================
Application Name: XYXZW4
Application Id: XYZ353WERX
Secret Key: XYZ86JBHHSD
Now I want regex to match only those "Application Name: value" which contain the "Secret Key: value" pair in windows powershell. I am not sure this may be the regex reference and it's not working on windows powerShell.
$input_path = ‘C:\Users\Steve\Downloads\input.txt’
$regex = '\s*Application Name:\s*.*\r?\n\s*(?=Application Id \(ClientId\):\s*.*\r?\n\s*Secret Key:\s*.*)|\s*Secret Key:\s*.*'
select-string -Path $input_path -Pattern $regex -AllMatches | Write-Output
All type of regexes work well on different platforms(tried few) but not on Windows powerShell.
The output should look like this:
Application Name: XYXZW3
Secret Key: XYZ86JBHHSD
Application Name: XYXZW4
Secret Key: XYZ86JBHHSD
Upvotes: 2
Views: 393
Reputation: 163277
You can use 2 capture groups if you want to get the value for Application name and Secret key
^[\p{Zs}\t]*Application Name:[\p{Zs}\t]*(.+)\r?\n[\p{Zs}\t]*Application Id:.*\r?\n[\p{Zs}\t]*Secret Key:[\p{Zs}\t]*(.+)
The pattern matches:
^
Start of string[\p{Zs}\t]*
Match optional horizontal whitespace charsApplication Name:[\p{Zs}\t]*
Match Application Name: and optional spaces(.+)
Capture group 1, the value of for Application Name\r?\n[\p{Zs}\t]*
Match an newline and optional spacesApplication Id:.*\r?\n
Match Applicatino Id: and the rest of the line[\p{Zs}\t]*Secret Key:[\p{Zs}\t]*
Match Secret Key: between optional spaces(.+)
Capture group 2, the value for Secret KeyIf you only want to match the value of the application name where there is a secret key present, you could also use lookarounds to assert the Application Name:
to the left, and Secret Key:
to the right without crossing a line that starts with at least ==
(?<=^\s*Application Name:\s*)\S.*(?=(?:\r?\n(?!\s*==).*)*\r?\n\s*Secret Key:)
Upvotes: 1
Reputation: 626747
I would rely on capturing groups here:
(?m)\bApplication Name:\s*(.+)(?:\n(?!\s*={3,}\r?$).*)*^\s*Secret Key:\s*(.+)
/\bApplication Name:\s*(.+)(?:\n(?!\s*={3,}\r?$).*)*^\s*Secret Key:\s*(.+)/gm
See the regex demo. Details:
\bApplication Name:
- a whole word Application
, space, Name,
:`\s*
- zero or more whitespaces(.+)
- Group 1: one or more chars other than line break chars as many as possible(?:\n(?!\s*={3,}\r?$).*)*
- any amount of lines that do not start with zero or more whitespaces followed with three or more =
chars up to the line end (\r?
is added here only in case you will have to deal with regex where $
with /m
flag does not match before a CR char, as in .NET)^
- start of a line\s*
- one or more whitespacesSecret Key:
- a Secret Key:
string\s*
- zero or more whitespaces(.+)
- Group 2: one or more chars other than line break chars as many as possibleUpvotes: 1
Reputation: 2363
To do it you need to use look-arounds.
/(?<=Application Name:)[^\n]*(?=[^=]*(?=Secret Key))/g
It captures everything between Application Name:
and \n
if after it Secret Key
appears before =
char.
It also captures all space
chars as well. If you don't want it and you know exact number of spaces, then you can change it to
/(?<=Application Name:\s{7})[^\n]*(?=[^=]*(?=Secret Key))/g
7
is the number of spaces to be skipped.
Demo.
Update:
To also catch Secret
value change to
/(?<=Application Name:\s{7})[^\n]*(?=[^=]*(?=Secret Key))/g
You need to handle two matches in a row as a pair of Application Name
and Secret Key
.
Demo.
Upvotes: 2