Negation in multiline regex? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
kunkel321
Posts: 969
Joined: 30 Nov 2015, 21:19

Negation in multiline regex?

05 May 2021, 15:09

My goal is to have a list like below, then one regex will find a sub-list that contains everything except not the lines that end with "-Opts]." Then, another regex will find only those lines that do end with it. Normally the caret ^ negates things. The Regex Quick Guide in the docs say that it doesn't work when the m) option is used though... So how do I hide those lines?

Also, just what does that caret (circumflex?) do in the below conditions?! If I run the script as show below, I get all 9 lines returned in %myVar%. But if I remove the caret, then only lines 1-7 are returned... Strange--yes?

Code: Select all

#NoEnv ; For security
#SingleInstance force
#Persistent

Haystack =
(
[1 PWN Consent for Initial EVAL]
[2 PWN Consent for Initial EVAL-Opts]
[3 PWN--Transfer]
[4 PWN--Transfer-Opts]
[5 PWN Need to do TRIennial REEVAL]
[6 PWN Need to do TRIennial REEVAL-Opts]
[7 PWN EARLY REEVAL REMOVE areas]
[8 PWN MDR -- NOT manifestation]
[9 PWN MDR -- IS manifestation]
)

Needle := "m)\[\N+[^-Opts]\]"

RegExMatch(Haystack, Needle, myVar) 
MsgBox Found:`n`n %myVar% 
return
ste(phen|ve) kunkel
User avatar
Smile_
Posts: 857
Joined: 03 May 2020, 00:51

Re: Negation in multiline regex?  Topic is solved

05 May 2021, 15:36

Not one regex

Code: Select all

Haystack =
(
[1 PWN Consent for Initial EVAL]
[2 PWN Consent for Initial EVAL-Opts]
[3 PWN--Transfer]
[4 PWN--Transfer-Opts]
[5 PWN Need to do TRIennial REEVAL]
[6 PWN Need to do TRIennial REEVAL-Opts]
[7 PWN EARLY REEVAL REMOVE areas]
[8 PWN MDR -- NOT manifestation]
[9 PWN MDR -- IS manifestation]
)

Result := ""
Loop, Parse, Haystack, `n, `r
If !(A_LoopField ~= "\Q-Opts]\E$")
    Result .= A_LoopField "`n"
Msgbox % Result

Result := ""
Loop, Parse, Haystack, `n, `r
If (A_LoopField ~= "\Q-Opts]\E$")
    Result .= A_LoopField "`n"
Msgbox % Result
Edit:
Replaced RegExMatch(A_LoopField, "\Q-Opts]\E$") with (A_LoopField ~= "\Q-Opts]\E$") (~= operator requires [v1.0.90+])
Last edited by Smile_ on 06 May 2021, 13:24, edited 4 times in total.
User avatar
kunkel321
Posts: 969
Joined: 30 Nov 2015, 21:19

Re: Negation in multiline regex?

05 May 2021, 16:23

Beautiful! Many thanks Smile_!
ste(phen|ve) kunkel
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Negation in multiline regex?

05 May 2021, 16:30

@kunkel321 - The group [^-Opts] is not saying “do not match -Opts” because a group of characters in brackets means match any character within this group. When you put the ^ at the start of it, it means match any character not contained in this group. So [^-Opts] is actually saying match any character other than -, O, p, t, or s.
User avatar
mikeyww
Posts: 26588
Joined: 09 Sep 2014, 18:38

Re: Negation in multiline regex?

05 May 2021, 16:41

This is not better or worse. OK, maybe it actually is worse (and might not always work)!

Code: Select all

str =
(
[1 PWN Consent for Initial EVAL]
[2 PWN Consent for Initial EVAL-Opts]
[3 PWN--Transfer]
[4 PWN--Transfer-Opts]
[5 PWN Need to do TRIennial REEVAL]
[6 PWN Need to do TRIennial REEVAL-Opts]
[7 PWN EARLY REEVAL REMOVE areas]
[8 PWN MDR -- NOT manifestation]
[9 PWN MDR -- IS manifestation]
)
SendInput % RegExReplace(str, "\V+-Opts]\n")
Send `n`n
SendInput % Trim(RegExReplace("`n" str "`n", "(\A|-Opts])\n\K\[.+?]\n(?=(\[.+?-Opts]|\Z))"), "`n")
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Negation in multiline regex?

05 May 2021, 17:03

mikeyww wrote:

Code: Select all

RegExReplace(str, "\V+-Opts]\n")
Try:

Code: Select all

str =
(
[10 PWN Need to do TRIennial REEVAL-Opts]
)
Better RegExReplace(Haystack, "\V*-Opts]\R?")
User avatar
mikeyww
Posts: 26588
Joined: 09 Sep 2014, 18:38

Re: Negation in multiline regex?

05 May 2021, 17:09

Great point, of course!

You proved me right when I claimed to be wrong....
User avatar
kunkel321
Posts: 969
Joined: 30 Nov 2015, 21:19

Re: Negation in multiline regex?

06 May 2021, 12:57

Thank you everyone, for the feedback!

-Smile, I think you might have broken yours when you took the RegExMatch out. It was working before, but maybe not now(??)

-Re the negation character: Now I'm wondering how you would do "not -Opts" Maybe with the caret on the outside?? ^[-Opts]
ste(phen|ve) kunkel
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Negation in multiline regex?

06 May 2021, 13:14

kunkel321 wrote: -Re the negation character: Now I'm wondering how you would do "not -Opts" Maybe with the caret on the outside?? ^[-Opts]
No, because outside of the brackets, the ^ tells it to anchor it to the beginning of the haystack, and the stuff in the brackets is still just a group of characters, so it would match any single character in that group.

Depending on how and where you want to match (or not match), there are various "negative" matching groups that say don't match this string, such as (?!-Opts).
User avatar
Smile_
Posts: 857
Joined: 03 May 2020, 00:51

Re: Negation in multiline regex?

06 May 2021, 13:21

@kunkel321
Screenshot.png
RegMatch
Screenshot.png (11.14 KiB) Viewed 552 times
It is supposed to be a shorthand of RegExMatch() but yeah it needs [v1.0.90+] as documented, I missed that sorry, then just put the old option or update the Auto-Hotkey version.
For me it works.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Negation in multiline regex?

06 May 2021, 13:32

kunkel321 wrote: how you would do "not -Opts"

Code: Select all

str =
(
[1 PWN Consent for Initial EVAL]
[2 PWN Consent for Initial EVAL-Opts]
[3 PWN--Transfer]
[4 PWN--Transfer-Opts]
[5 PWN Need to do TRIennial REEVAL]
[6 PWN Need to do TRIennial REEVAL-Opts]
[7 PWN EARLY REEVAL REMOVE areas]
[8 PWN MDR -- NOT manifestation]
[9 PWN MDR -- IS manifestation]
)
MsgBox, % RegExReplace(str, "m`a)^(?!\V*-Opts]$)\V*\R?")
User avatar
kunkel321
Posts: 969
Joined: 30 Nov 2015, 21:19

Re: Negation in multiline regex?

07 May 2021, 10:43

@Smile_: I guess you're right... I just tried your above code again and it did work. I'm not sure what I did wrong last time...

Mikeyww and Teadrinker, I'm still trying to digest your patterns! LOL. I'm actually not new to regexes, though it might seem like I am from this thread. :mrgreen:

New related question: I see that Teadrinker has used \V in a couple spots. The docs indicate that this is a "vertical tab." Is that how it is used here?
ste(phen|ve) kunkel
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Negation in multiline regex?

07 May 2021, 11:04

kunkel321 wrote: New related question: I see that Teadrinker has used \V in a couple spots. The docs indicate that this is a "vertical tab." Is that how it is used here?
The docs do not indicate that. They indicate that it matches a character that is not a vertical whitespace character. You apparently are referrring to \v. It's similar to how \s matches a whitespace character and \S matches any non-whitespace character.
User avatar
mikeyww
Posts: 26588
Joined: 09 Sep 2014, 18:38

Re: Negation in multiline regex?

07 May 2021, 11:11

Very true.

@teadrinker has a better version than mine, so would have a look at that one.
User avatar
kunkel321
Posts: 969
Joined: 30 Nov 2015, 21:19

Re: Negation in multiline regex?

07 May 2021, 17:15

boiler wrote:
07 May 2021, 11:04
The docs do not indicate that. They indicate that it matches a character that is not a vertical whitespace character. You apparently are referrring to \v. It's similar to how \s matches a whitespace character and \S matches any non-whitespace character.
Yea, my bad. I think I accidentally typed a forward slash into the 'find' box and found this (which isn't even part of a pattern) at the very bottom of the table that shows the different options.
`a [v1.0.46.06+]: `a recognizes any type of newline, namely `r, `n, `r`n, `v/VT/vertical tab/chr(0xB), `f/FF/formfeed/chr(0xC), and NEL/next-line/chr(0x85). [v1.0.47.05+]: Newlines can be restricted to only CR, LF, and CRLF by instead specifying (*ANYCRLF) in uppercase at the beginning of the pattern (after the options); e.g. im)(*ANYCRLF)^abc$.
ste(phen|ve) kunkel

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Rohwedder and 133 guests