RegEx that checks if a character doesn't exist in a string - regex

I'm having a hard time trying to figure out how to create a RegEx that checks if a character doesn't appear at any moment of a line following a pattern.
I have the following log:
3/9/18, 17:47 - Person 1: Hello guys!
3/10/18, 22:59 - Person 2 joined the group.
3/10/18, 09:35 - Person 2: Sup!
What's cracking?
3/10/18, 09:36 - Person 1: Not much...
And I'm reading one line at a time, so I need to discard lines that have the following pattern: date, hour - warning., like the second line in the example above, since they are lines of the system and not of the conversation.
All I managed to do until now is this RegEx:
\d*\/\d*\/\d*, \d*:\d* - (?!\:)
But the negative lookeahead (?!\:) only checks the character after the -, not the rest of the string. How can I force this RegEx to check if there's no : in the rest of the string?
Here's a demo.

You could use a negated character class [^ matching 0+ times not a newline or : and then match : inside the negative lookahead
Note to match \d+ to match 1+ digits and not match //, : -
\d+/\d+\/\d+, \d+:\d+ - (?![^\r\n:]*:)
About the last part:
(?! Negative lookahead
[^\r\n:]* match 0+ times any char other than a newline or colon
: Match the colon
) Close lookahead
Regex demo

How can I force this RegEx to check if there's no : in the rest of the
string?
With lookahead assertion:
\d+/\d+\/\d+, \d+:\d+ -(?=[^:]+$)
https://regex101.com/r/KD3kW4/1

Related

Regex: match patterns starting from the end of string

I wish to match a filename with column and line info, eg.
\path1\path2\a_file.ts:17:9
//what i want to achieve:
match[1]: a_file.ts
match[2]: 17
match[3]: 9
This string can have garbage before and after the pattern, like
(at somewhere: \path1\path2\a_file.ts:17:9 something)
What I have now is this regex, which manages to match column and line, but I got stuck on filename capturing part.. I guess negative lookahead is the way to go, but it seems to match all previous groups and garbage text in the end of string.
(?!.*[\/\\]):(\d+):(\d+)\D*$
Here's a link to current implementation regex101
You can replace the lookahead with a negated character class:
([^\/\\]+):(\d+):(\d+)\D*$
See the regex demo. Details:
([^\/\\]+) - Group 1: one or more chars other than / and \
: - a colon
(\d+) - Group 2: one or more digits
: - a colon
(\d+) - Group 3: one or more digits
\D*$ - zero or more non-digit chars till end of string.

Regex (PCRE): Match all digits in a line following a line which includes a certain string

Using PCRE, I want to capture only and all digits in a line which follows a line in which a certain string appears. Say the string is "STRING99". Example:
car string99 house 45b
22 dog 1 cat
women 6 man
In this case, the desired result is:
221
As asked a similar question some time ago, however, back then trying to capture the numbers in the SAME line where the string appears ( Regex (PCRE): Match all digits conditional upon presence of a string ). While the question is similar, I don't think the answer, if there is one at all, will be similar. The approach using the newline anchor ^ does not work in this case.
I am looking for a single regular expression without any other programming code. It would be easy to accomplish with two consecutive regex operations, but this not what I'm looking for.
Maybe you could try:
(?:\bstring99\b.*?\n|\G(?!^))[^\d\n]*\K\d
See the online demo
(?: - Open non-capture group:
\bstring99\b - Literally match "string99" between word-boundaries.
.*?\n - Lazy match up to (including) nearest newline character.
| - Or:
\G(?!^) - Asserts position at the end of the previous match but prevent it to be the start of the string for the first match using a negative lookahead.
) - Close non-capture group.
[^\d\n]* - Match 0+ non-digit/newline characters.
\K - Resets the starting point of the reported match.
\d - Match a digit.

Return data between first and fifth backslash

I need some regex that will return the value between first and fifth backslash has highlighted below in bold:
dataCapture/22E6F953EA6D445C8FB20E9D29A977D7/6.20.0-3c1e4b0c459eb93e43eb64fed7447a41fb4d4029/uuid_2b896c17-eb5c-4fd1-ae44-78dcda6c8ee9/36/3D1C3A58A039103375D320E524500A74
So far I've only been able to come up with regex that returns data up till the first backslash:
\/dataCapture\/(.+?)\/
How do I extend the above to include data up to the fifth backslash?
Might not be the cleanest but that makes the job done:
const regex = /dataCapture\/([a-zA-Z0-9]+\/[a-zA-Z0-9\.\-]+\/[a-zA-Z0-9\.\-\_]+\/[0-9]+)\/.*/;
const value = "dataCapture/22E6F953EA6D445C8FB20E9D29A977D7/6.20.0-3c1e4b0c459eb93e43eb64fed7447a41fb4d4029/uuid_2b896c17-eb5c-4fd1-ae44-78dcda6c8ee9/36/3D1C3A58A039103375D320E524500A74";
console.log(value.match(regex)[1]); // => 22E6F953EA6D445C8FB20E9D29A977D7/6.20.0-3c1e4b0c459eb93e43eb64fed7447a41fb4d4029/uuid_2b896c17-eb5c-4fd1-ae44-78dcda6c8ee9/36
In order to solve this regex pattern, you have to use the following code:
^\/dataCapture\/(.+?)\/(.+?)\/(.+?)\/(.+?)\/
You can test this regex in this site.
I am not familiar with JMeter, but I understand it uses a slight variant of Perl5's regex engine, so I expect matching the following regular expression will extract the string of interest.
(?<=^dataCapture\/)(?:[^\/]*\/){3}[^\/]*(?=\/)
demo
The regex engine performs the following operations.
(?<= : begin positive lookbehind
^ : match beginning of string
dataCapture\/ : match 'dataCapture\/
) : end positive lookbehind
(?:[^\/]*\/) : match 0+ charsother than '/', followed by '/', in
a non-capture group
{3} : execute the non-capture group 3 times
[^\/]* : match 0+ chars other than '/'
(?=\/) : positive lookahead asserts that the next char is '/'

Regex to get value from <key, value> by asserting conditions on the value

I have a regex which takes the value from the given key as below
Regex .*key="([^"]*)".* InputValue key="abcd-qwer-qaa-xyz-vwxc"
output abcd-qwer-qaa-xyz-vwxc
But, on top of this i need to validate the value with starting only with abcd- and somewhere the following pattern matches -xyz
Thus, the input and outputs has to be as follows:
I tried below which is not working as expected
.*key="([^"]*)"?(/Babcd|-xyz).*
The key value pair is part of the large string as below:
object{one="ab-vwxc",two="value1",key="abcd-eest-wd-xyz-bnn",four="obsolete Values"}
I think by matching the key its taking the value and that's y i used this .*key="([^"]*)".*
Note:
Its a dashboard. you can refer this link and search for Regex: /"([^"]+)"/ This regex is applied on the query result which is a string i referred. Its working with that regex .*key="([^"]*)".* above. I'm trying to alter with that regexGroup itself. Hope this helps?
Can anyone guide or suggest me on this please? That would be helpful. Thanks!
Looks like you could do with:
\bkey="(abcd(?=.*-xyz\b)(?:-[a-z]+){4})"
See the demo online
\bkey=" - A word-boundary and literally match 'key="'
( - Open 1st capture group.
abcd - Literally match 'abcd'.
(?=.*-xyz\b) - Positive lookahead for zero or more characters (but newline) followed by literally '-xyz' and a word-boundary.
(?: - Open non-capturing group.
-[a-z]+ - Match an hyphen followed by at least a single lowercase letter.
){4} - Close non-capture group and match it 4 times.
) - Close 1st capture group.
" - Match a literal double quote.
I'm not a 100% sure you'd only want to allow for lowercase letter so you can adjust that part if need be. The whole pattern validates the inputvalue whereas you could use capture group one to grab you key.
Update after edited question with new information:
Prometheus uses the RE2 engine in all regular expressions. Therefor the above suggestion won't work due to the lookarounds. A less restrictive but possible answer for OP could be:
\bkey="(abcd(?:-\w+)*-xyz(?:-\w+)*)"
See the online demo
Will this work?
Pattern
\bkey="(abcd-[^"]*\bxyz\b[^"]*)"
Demo
You could use the following regular expression to verify the string has the desired format and to match the portion of the string that is of interest.
(?<=\bkey=")(?=.*-xyz(?=-|$))abcd(?:-[a-z]+)+(?=")
Start your engine!
Note there are no capture groups.
The regex engine performs the following operations.
(?<=\bkey=") : positive lookbehind asserts the current
position in the string is preceded by 'key='
(?= : begin positive lookahead
.*-xyz : match 0+ characters, then '-xyz'
(?=-|$) : positive lookahead asserts the current position is
: followed by '-' or is at the end of the string
) : end non-capture group
abcd : match 'abcd'
(?: : begin non-capture group
-[a-z]+ : match '-' followed by 1+ characters in the class
)+ : end non-capture group and execute it 1+ times
(?=") : positive lookahead asserts the current position is
: followed by '"'

Regex to capture a group, but only if preceded by a string and followed by a string

There's a few examples of the 'typical' solution to the problem, here in SO and elsewhere, but we need help with a slightly different version.
We have a string such as the following
pies
bob likes,
larry likes,
harry likes
cakes
And with the following regexp
(?<=pies\n|\G,\n)(\w+ likes)
Only when the string commences with pies we can capture the 'nnn likes' as expected, however, we'd also need that the capture fails if it doesn't end with 'cakes', and our attempts at doing so have failed.
Link to the regex101: https://regex101.com/r/uDNWXN/1/
Any help appreciated.
I suggest adding an extra lookahead at the start, to make sure there is cakes in the string:
(?s)(?<=\G(?!^),\n|pies\n(?=.*?cakes))(\w+ likes)
See the regex demo (no match as expected, add some char on the last line to have a match).
Pattern details
(?s) - DOTALL/singleline modifier to let . match any chars including line breaks
(?<= - a positive lookbehind that requires the following immediately to the left of the current location:
\G(?!^),\n - right after the end of previous match, a comma and then a newline
| - or
^pies\n(?=.*cakes) - start of string, pies, newline not followed with any 0+ chars as many as possible, and then a cakes string
) - end of the lookbehind
(\w+ likes) - Group 1: any one or more letters, digits or underscores and then a space and likes.