How to NOT trigger on a Perl RegExp

Post Reply
User avatar
SlySven
Posts: 1019
Joined: Mon Mar 04, 2013 3:40 pm
Location: Deepest Wiltshire, UK
Discord: SlySven#2703

How to NOT trigger on a Perl RegExp

Post by SlySven »

The Mud I once played (before I got into coding for Mudlet ;) ) reports the Room Name in Cyan on Black - so it is relatively straightforward to have a Trigger to detect that - at least since I fixed the bug that prevented dark-cyan and bright-white {see Bug Report #1103645 and PRs #235 (development) #256 (release_30) } foreground colour triggers from working.

The trouble I am having is that the Immortals also use that colour for their pronouncements - I have a PCRE which will detect THOSE as:

Code: Select all

^(\w+) speaks from the (\w+): '(.*)')$
but how do I ensure that lines that DO match this pattern DO NOT fire a trigger that is to pass "Room Names"?

I did think that the PCRE negative look ahead (?!...) might do this so that I would use this as a second line below the Color Trigger:

Code: Select all

^(?!((\w+) speaks from the (\w+): '(.*)'))$
but that does not work as far as I can tell using https://www.regex101.com/ - so how can I match:

CYAN text which is anything EXCEPT the form:

WORD speaks from the WORD: 'SENTENCE'

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: How to NOT trigger on a Perl RegExp

Post by Jor'Mox »

Well, for one thing, I'm pretty sure you can't use capture groups inside of a negative look ahead, which may well be your problem. The key though is that you need to make it an AND trigger, and not a regular OR trigger. While it will require a line to follow whatever line you are trying to match (because it is a multiline / AND trigger), it works when I set up a similar trigger, with one positive and one negative match (and no capture groups inside the lookahead).

User avatar
SlySven
Posts: 1019
Joined: Mon Mar 04, 2013 3:40 pm
Location: Deepest Wiltshire, UK
Discord: SlySven#2703

Re: How to NOT trigger on a Perl RegExp

Post by SlySven »

So I have to convert the three capture groups {two word (\w+) and the anything (.*)} to non-captures i.e. (?:\w+) and (?:.*) - that makes sense as those groups are ALL present IN LINES I DON'T WANT - ah ha! Perhaps I can make it simpler because there is never going to be a string I DO want which will have the fixed text "speaks from the" as a room location text - I want to capture the entire line / trigger if the text does NOT contain the fixed string "speaks from the" and apparently this can be done with:

Code: Select all

^((?!speaks from the).)*$
according to this answer on Stack Overflow. :D

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: How to NOT trigger on a Perl RegExp

Post by Jor'Mox »

I think you could just have done this: ^(?!\w+ speaks from the \w+: '.*')
The color trigger part of it should still capture all of the text of that color into matches[1], so there shouldn't be a need for additional capture groups.

User avatar
SlySven
Posts: 1019
Joined: Mon Mar 04, 2013 3:40 pm
Location: Deepest Wiltshire, UK
Discord: SlySven#2703

Re: How to NOT trigger on a Perl RegExp

Post by SlySven »

It doesn't seem to work in the Regexp101 tester - as I read it I wonder what the negative lookahead (?!...) acts on - is it just the first \w+ or the whole \w+ speaks from the \w+: '.* though, given that it is a negative look ahead does that not mean there is a match if the input is NOT what is in the string at the point where this string is considered?

Ah, ha got it - this does it WITH the wild-carding:

Code: Select all

^((?!\w+ speaks from the \w+: '.*').*)$
Tested with:
"A Road North from the Dark Fortress" - matches: YES - the sort of thing expected and wanted to match and be captured.
"Fred speaks of the Dark: 'Golly, who turned the lights off?'" - matches: YES - close to unwanted sentence but it does not match what we don't want so does pass through and matches[2] will contain the whole wanted string.
"Flash speaks from the Light: 'Remember Folks, you are our House Guests here so play nicely together and I won't have to set Viv on you...!'" - matches: NO - rejected as wanted. :D

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: How to NOT trigger on a Perl RegExp

Post by Jor'Mox »

Ah. Yeah, if you were terminating the pattern, then you definitely needed a .* after the negative look ahead, otherwise it would only match empty strings. I had left the $ off of my pattern intentionally, to avoid that issue, though I can see the appeal of capturing it with a regular capture group. I normally don't work with matches[1] either.

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: How to NOT trigger on a Perl RegExp

Post by Vadi »

I'd also make that expensive-looking regex in a gated trigger, have the "speaks from the" substring get checked first.

User avatar
SlySven
Posts: 1019
Joined: Mon Mar 04, 2013 3:40 pm
Location: Deepest Wiltshire, UK
Discord: SlySven#2703

Re: How to NOT trigger on a Perl RegExp

Post by SlySven »

Well, there is a check for cyan on black colour check prior to this one so it only gets run on that colour MUD output - which is only going to be things I want (room names) for this trigger (or Immortal speech - which I also want separately - but NOT in this trigger) as it happens there is not going to be a room containing " speaks from the " anyhow (I hope) so the test could probably be simpler with little chance of false positives anyhow. I just hope that this can give pointers to others wondering how to get the desired "I know what I DON'T want to trigger on" result they need... 8-)

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: How to NOT trigger on a Perl RegExp

Post by Vadi »

One way would be to run a Lua function as the 3rd pattern.

Post Reply