Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ General
➜ Multiline Trigger Problem: Match Limit
Multiline Trigger Problem: Match Limit
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Tharius
(29 posts) Bio
|
Date
| Mon 05 May 2014 07:07 PM (UTC) Amended on Mon 05 May 2014 09:32 PM (UTC) by Tharius
|
Message
| I am trying to write a trigger to capture a list of mobiles killed by me.
To this means I wrote a script that I'm satisfied with for maintaining the list (kill buffer list) but the trigger to call the script function is giving me the following error:
Error executing regular expression: Match Limit
This of course occurs during long input sequences where many lines could be potential matches.
The regular expression is:
Your? \w*\s?(?:\*+ \w* \*+|\w*) ((?:[\w,\']+\s?)*)[.|!]\n((?:[\w,\']+\s?)*) is DEAD!!\Z
Which matches things like:
Your pierce _butchers_ the guard!
The guard is DEAD!!
Of course the first segment is pretty common:
You jolt the guard!
You jolt the guard!
You jolt the guard!
You dodge the guard's attack.
You dodge the guard's attack.
You dodge the guard's attack.
You dodge the guard's attack.
But the second line is the part that gets what I want. The two work together because you want to know "who got the hit on the line prior and to which mob" in case multiple people are fighting in the same room.
For example the following is NOT a match:
Jimbo's pierce _butchers_ the guard!
The guard is DEAD!!
I tried changing the \n in the middle of the trigger to $ or using \n$ or \s+$ which aren't doing anything for me (in fact don't match anymore) but that's just hacking around rather than understanding.
I am using Mush 4.73
Thanks!
<triggers>
<trigger
enabled="y"
group="thKillBuffer"
lines_to_match="2"
match="Your? \w*\s?(?:\*+ \w* \*+|\w*) ((?:[\w,\']+\s?)*)[.|!]\n((?:[\w,\']+\s?)*) is DEAD!!\Z"
multi_line="y"
regexp="y"
script="UpdateKillBuffer"
send_to="12"
sequence="100"
lowercase_wildcard="y"
>
<send>
</send>
</trigger>
</triggers>
EDIT:
I did add \A before "Your?" in the regex to no improvement in the conditions.
Also apologies for the double post. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #1 on Tue 06 May 2014 07:55 PM (UTC) |
Message
| I can reproduce this. Since you are matching on two lines we need to find which two cause this issue.
This does not:
You jolt the guard!
You jolt the guard!
This does not:
You dodge the guard's attack.
You dodge the guard's attack.
This does:
You jolt the guard!
You dodge the guard's attack.
According to the PCRE documentation:
Quote:
The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats.
Internally, pcre_exec() uses a function called match(), which it calls repeatedly (sometimes recursively). The limit set by match_limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string.
I'll try to work out what is causing this, but something like this would be the sort of thing:
There are many ways that could match. The above regexp, for example, also causes the "match limit" error on this line:
You dodge the guard's attack with a blow to the head and then run away.
However the error is not raised for a shorter line. Basically PCRE is working out thousands of ways that the first few wildcard characters could be filled in. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #2 on Tue 06 May 2014 08:15 PM (UTC) |
Message
| I couldn't quite see where the match limit was coming from (but I suspect the second line) however this simpler version seems to work OK:
<triggers>
<trigger
enabled="y"
group="thKillBuffer"
lines_to_match="2"
match="^(Your?).+[.|!]\n([\w\s]+) is DEAD!!\Z"
multi_line="y"
regexp="y"
send_to="12"
sequence="100"
lowercase_wildcard="y"
>
<send>print "matched, wildcard 1 = %1, wildcard 2 = %2"</send>
</trigger>
</triggers>
|
For advice on how to copy aliases, timers or triggers from within MUSHclient, and paste them into a forum message, please see Copying XML.
|
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #3 on Tue 06 May 2014 08:17 PM (UTC) |
Message
| Or even this regexp:
^(Your?).+[.|!]\n((?:[\w,\']+\s?)*) is DEAD!!\Z
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Tharius
(29 posts) Bio
|
Date
| Reply #4 on Wed 07 May 2014 02:34 AM (UTC) |
Message
| Hi Nick,
I noticed that it was also generating the match limit error message even on room descriptions that had nothing to do with a fight at all, so I assume that my regex is too complex.
I will try yours and see if it fits my needs and will report back, thanks for your help. With another piece of software I could actually access the line prior to a trigger firing but it encouraged me to be lazy in my thinking with regards to multiline regexs. | Top |
|
Posted by
| Tharius
(29 posts) Bio
|
Date
| Reply #5 on Wed 07 May 2014 02:48 AM (UTC) |
Message
| Your blast **** SMITES **** the street peddler!
The street peddler is DEAD!!
matched, wildcard 1 = your, wildcard 2 = the street peddler
Well, there certainly was no problem with the match limit, however we did lose some data in this process.
You or your: check!
Does the mob from line 1 match the mob in line 2? Lost.
I mean, this is a real edge case which might occur if you are in a room with several mobs, you hit one but another is killed by someone else in the room, so what you have proposed is likely very sufficient. At this point it's almost academic to figure the rest out.
We have a breakdown like this:
[You|Your|Charname.."'s"] <damage descriptor> <damage amount descriptor> <mob name>[.|!]
If the string starts 'You' then the damage descriptor is omitted (perhaps it's easier to just use 2 triggers.
Damage amount descriptor may or may not be enclosed in asterisks.
Anyway. Perhaps it's easier to break it into multiple triggers matching the different cases if I find I really really must have this level of accuracy.
Thanks Nick | Top |
|
Posted by
| Tharius
(29 posts) Bio
|
Date
| Reply #6 on Wed 07 May 2014 04:59 PM (UTC) |
Message
| Hi Nick,
I used your regex and gave the script a whirl, but unfortunately hit the same issue.
I think I'm going to have to try to enumerate the potential smaug messages to cut down on the .* or \w* type matches. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #7 on Wed 07 May 2014 07:47 PM (UTC) Amended on Wed 07 May 2014 07:48 PM (UTC) by Nick Gammon
|
Message
| Try my first regexp, is that OK?
^(Your?).+[.|!]\n([\w\s]+) is DEAD!!\Z
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #8 on Wed 07 May 2014 07:50 PM (UTC) |
Message
| In your regexp, do you really get a | in the output?
If not, you don't need it (the vertical bar) inside the square brackets, it already is a set (this OR that) without the | symbol. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Tharius
(29 posts) Bio
|
Date
| Reply #9 on Thu 08 May 2014 05:02 PM (UTC) |
Message
|
Nick Gammon said:
In your regexp, do you really get a | in the output?
If not, you don't need it (the vertical bar) inside the square brackets, it already is a set (this OR that) without the | symbol.
Right! Good bye vertical bar :> | Top |
|
Posted by
| Tharius
(29 posts) Bio
|
Date
| Reply #10 on Thu 08 May 2014 05:19 PM (UTC) |
Message
|
Nick Gammon said:
match="^(Your?).+[.!]\n([\w\s]+) is DEAD!!\Z"
This version (your first) seemed to work well for quite a while (meaning I didn't test it thoroughly but didn't see it crash either).
I'm wondering if it would be sufficient to grab the .+ group and do a string comparison inside the script to verify the two are the same (eg a right handed string match). | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #11 on Thu 08 May 2014 07:42 PM (UTC) Amended on Thu 08 May 2014 07:43 PM (UTC) by Nick Gammon
|
Message
|
Tharius said:
With another piece of software I could actually access the line prior to a trigger firing but it encouraged me to be lazy in my thinking with regards to multiline regexs.
You can do that easily enough here. Make a trigger that matches any line (or maybe a combat line) and save it in a variable. Give it a low sequence number so it fires before other triggers, and set "keep evaluating". Also make it "send to script after omit" so that it doesn't match the current line if the other trigger matches as well. eg.
<triggers>
<trigger
enabled="y"
keep_evaluating="y"
match="*"
send_to="14"
sequence="1"
>
<send>previous_line = "%1"
previous_line_count = GetLineCount ()</send>
</trigger>
</triggers>
|
For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.
|
Now your other trigger can be a simple one-line trigger:
<triggers>
<trigger
custom_colour="2"
enabled="y"
match="* is DEAD!!"
send_to="12"
sequence="100"
>
<send>print ("Previous line was:", previous_line)</send>
</trigger>
</triggers>
With a bit of work there with a Lua regexp (not a PCRE one) you can pull out the name of the mobs from both lines, do your comparison, and make your decisions.
The line count (GetLineCount) can be used to check that the previous line was indeed the previous line (eg. if you make the first trigger a combat trigger rather than any trigger). |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
30,401 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top