Multiple line parsing

Posted by Indiana on Tue 25 May 2004 07:01 PM — 2 posts, 13,502 views.

Romania #0
I come acros to a quite interesting problem I still haven't solved.
The text I wish to parse is:

(something)You are:
deaf.
blind.
....

I want this snippet to be triggered and call a VBScript function so that I can parse the next n lines (to actualy modify some variables acording to my script).
I am aware that a simple version would be to actually trigger 'deaf.', 'blind.' and change some variables acording to them but the context is a bit different. It is actually a diagnose and some texts there can be defences as well as afflictions (so I want to be deaf and blind, but not paralysed).
This is why I want to parse all the lines that come after the text 'You are:' and use a function to verify.
Thank you.
Amended on Tue 25 May 2004 07:03 PM by Indiana
Australia Forum Administrator #1
You want a multiple-line trigger. Wade through this posting:

http://www.gammon.com.au/forum/?bbsubject_id=4087

It describes in some detail the design that went into the new multi-line triggers in MUSHclient.

Basically you want to match on something like:


<triggers>
<trigger
enabled="y"
lines_to_match="10"
match="(?x)You\ are:\n ( ( (?P&lt;d&gt;deaf) | (?P&lt;b&gt;blind) | (?P&lt;p&gt;paralysed) ) \.\n )+ &lt;.*&gt;.*\z"
multi_line="y"
regexp="y"
send_to="2"
sequence="100"
>
<send>
deaf = %&lt;d&gt;
blind = %&lt;b&gt;
paralysed = %&lt;p&gt;
</send>
</trigger>
</triggers>


This was an interesting one to get right. What this does is set up a multi-line trigger that matches on "deaf", "blind", "paralysed" (in any order) and puts the results into named wildcards.

If your "send" box you could test them (in a "send to script") like this:


if "%<p>" <> "paralysed" then
  if "%<d>" = "deaf" then
    send "drink red potion"
  end if  ' deaf
end if  ' not paralysed


The tricky bit was terminating the regular expression. Because it is matching any number of lines that *might* follow it needs a "terminating" line, one that tells it that it is *not* an affliction line. I have chosen something with:

< (something) > (something)

(ie. a prompt line) but you might tailor it to what you actually see.

In fact, after a bit more experimenting, this works better:


<triggers>
<trigger
enabled="y"
lines_to_match="10"
match="(?x)You\ are:\n ( ( (?P&lt;d&gt;deaf) | (?P&lt;b&gt;blind) | (?P&lt;p&gt;paralysed) ) \.\n )+ (?!(deaf|blind|paralysed)).*\z"
multi_line="y"
regexp="y"
send_to="2"
sequence="100"
>
<send>%%0 = %0
deaf = %&lt;d&gt;
blind = %&lt;b&gt;
paralysed = %&lt;p&gt;
</send>
</trigger>
</triggers>


What this does is match:

You are: (followed by)
deaf.
blind.
paralysed. (in any order, and optional)

Followed by a line that does *not* start with
deaf or blind or paralysed.