Regexpes - Need help with designing one.

Posted by Rynne on Fri 18 Jan 2008 01:45 PM — 4 posts, 17,493 views.

France #0
Hello folks, I have a little problem.

I need to capture either

"You shove Bob."

or

"Bob shoves you."

but not

"Bob shoves John."


All while making sure that "Bob" always gets assigned to the same wildcard. Using regexpes. In only one trigger.

So far I came up with "((.*?) shoves you|You shove (.*?))\."

But somehow it feeds the whole line ("You shove Bob") in the first wildcard, and "Bob" in either the 2nd or the 3rd wildcard. (the other one being an empty string)

I need your help.
Amended on Fri 18 Jan 2008 01:47 PM by Rynne
Netherlands #1
That is because parentheses denote captured groups, as in '(' + group + ')'. So since the outer group is the first one it encounters, it will catch it.

There's a simple way to negate this behaviour, and that is to specify it not to capture, like this:

(?:(.*?) shoves you|You shove (.*?))\.

That could be simplified if you knew each name was only one word:

(?:(\w+) shoves you|You shove (\w+))\.

And if you preferred, you could get rid of the entire non-capturing group all together like this:

(\w+) shoves? (\w+)\.

The ? means 0 or 1 character of the group before it - in this case, the letter s. By checking the second captured group and seeing if it equals 'you', you are able to tell what case of the trigger it is (if you needed it). Additionally, I added a ^ (=beginning of line) in front and a $ (=end of line) at the end to signify that this is an entire line of output and not part of something like "Poo smells. Poo shoves the kingdom. Pee conquers all!" which your current trigger would fire on.

Edit: Oops, sleepiness. Misread it a bit, but you could of course perform the 'you' check on the first wildcard too, if you needed. But probably, the best solution would remain to be:

^(?:(\w+) shoves you|You shove (\w+))\.$
Amended on Fri 18 Jan 2008 03:42 PM by Worstje
Australia Forum Administrator #2
Quote:

All while making sure that "Bob" always gets assigned to the same wildcard. Using regexpes. In only one trigger.


How about this?


<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="(?J)((?P&lt;who&gt;.*?) shoves you|You shove (?P&lt;who&gt;.*?))\."
   regexp="y"
   send_to="2"
   sequence="100"
  >
  <send>who is %&lt;who&gt;</send>
  </trigger>
</triggers>


I have used a named wildcard here (who) to capture the name. I also used the "allow duplicate names" option (?J).

Now, whichever branch matches, it still makes "who" be Bob.

Here is my test:


You shove Bob.
who is Bob
Bob shoves you.
who is Bob
Bob shoves John.
(no match)



You need to see http://www.mushclient.com/pasting to get a proper copy of this, inside the match text &lt; is really a < symbol.
Amended on Fri 18 Jan 2008 07:08 PM by Nick Gammon
France #3
Thanks muchly, I got it to work.