Register forum user name Search FAQ

Gammon Forum

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 ➜ Lua ➜ Probable RegEx Error

Probable RegEx Error

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Terry   USA  (87 posts)  Bio
Date Mon 14 Dec 2009 04:43 PM (UTC)

Amended on Mon 14 Dec 2009 05:30 PM (UTC) by Terry

Message
I wrote an alias to detect, view, and set fighting styles on a MUD. Everything works as expected, except for actually setting the style. When I try to set a style, it accepts something like ast kick 80 130, but doesn't send astyle kick 80 130, and also doesn't set the strength and speed variables. I tried setting them manually, and the script worked with viewing the current style, and would send it if I did ast <style>, but wouldn't do anything if I tried to change the str/spd.

<aliases>
  <alias
   name="astyle"
   match="^(c|r)?as(?:t|tyle)?(d| )?(kung|kick|kar|aik)?(?: )?([0-300])?(?: )?([0-300])?$"
   enabled="y"
   group="combat"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>--[[ See current style ]]
if "%1" == "c" and "%3%4%4" == "" then
  if GetVariable("style") == nil or GetVariable("strength") == nil
      or GetVariable("speed") == nil then
    print "No style has been set."
  else
    print("Your current style: " .. GetVariable("style") .. " " ..
          GetVariable("strength") .. "% " .. GetVariable("speed") .. "%")
  end -- if

--[[ Reset current style ]]
elseif "%1" == "r" and "%3%4%5" == "" then
  DeleteVariable("style")
  DeleteVariable("strength")
  DeleteVariable("speed")
  print "All variables have been reset."

--[[ Detect best style ]]
elseif "%1" == "" and "%2" == "d" and "%3%4%5" == "" then
  ColourNote("silver", "", "asd")
  SendNoEcho("astyle detect strength")
  SendNoEcho("astyle detect speed")

--[[ Set new style ]]
elseif "%1%2" == " " then
  if "%3" ~= "" then
    SetVariable("style", "%3")
  end -- if
  local style = GetVariable("style")

  if "%4" ~= "" then
    SetVariable("strength", "%4")
  end -- if
  local str = GetVariable("strength")

  if "%5" ~= "" then
    SetVariable("speed", "%5")
  end -- if
  local spd = GetVariable("speed")

  Send("astyle " .. style .. " " .. str .. " " .. spd)

--[[ Display syntax ]]
else
  print "Syntax: cas[tyle][d]                         -- Display current style"
  print "        ras[tyle][d]                         -- Reset style"
  print "        as[tyle]d                            -- Detect best style"
  print "        as[tyle] &lt;style&gt; &lt;strength&gt; &lt;speed&gt;  -- Select new style"

end -- if</send>
  </alias>
</aliases>
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #1 on Mon 14 Dec 2009 04:54 PM (UTC)
Message
Quote:
([0-300])?(?: )?([0-300])?


This doesn't do what you think it does...

Character classes work like this:

[X*]

where X is of the form:

1. Y-Z, meaning all characters in between Y and Z (by their numeric character values)
or
2. A (meaning the single character)

Therefore [0-300] means the characters 0 through 3, or 0, or 3, i.e. 0,1,2,3.



By the way, it's helpful if you post a minimal example so that we can see exactly how the alias is failing, without all the other stuff to sort through.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Terry   USA  (87 posts)  Bio
Date Reply #2 on Mon 14 Dec 2009 05:26 PM (UTC)
Message
Ah, okay. Thanks :) I changed it to the following:
"^(c|r)?as(?:t|tyle)?(d| )?(kung|kick|kar|aik)?(?: )?([1-3]\d{1,2}|\d{1,2})?(?: )?([1-3]\d{1,2}|\d{1,2})?$"


However, this still allows the range to be from 0-399, instead of 0-300. I know this is just a personal alias, but I'm a perfectionist, and I also don't like not knowing. :3 How can I restrict it to 0-300? The closest I can get is 0-299....


Also, on a different note, when I type something like asd kick, the alias just ignores it and passes it on as is, instead of displaying the syntax. Why is that?



Edit: As I was writing, I just thought of doing this:
"^(c|r)?as(?:t|tyle)?(d| )?(kung|kick|kar|aik)?(?: )?(300|[1-2]\d{1,2}|\d{1,2})?(?: )?(300|[1-2]\d{1,2}|\d{1,2})?$"

This seems to work, but it's really nasty to have such a long RegEx... Is there any way of simplifying it? Thanks!
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #3 on Mon 14 Dec 2009 05:37 PM (UTC)
Message
([1-9]?[0-9]|[12][0-9][0-9]|300)


I cut out the rest of the regex and just wrote something that will match any number from 1 to 300. It's a little messy, and it could be shortened a little by allowing 000, 070, 009, etc. but this seems to work fine.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Quixadhal   (4 posts)  Bio
Date Reply #4 on Mon 14 Dec 2009 05:40 PM (UTC)
Message
This might be helpful.

http://www.pythonregex.com/

If Lua's regex syntax is too different, there was an old TCL program that was more flexible, but you'll have to find it. I think it was called vreg or something similar.
Top

Posted by Terry   USA  (87 posts)  Bio
Date Reply #5 on Mon 14 Dec 2009 05:42 PM (UTC)

Amended on Mon 14 Dec 2009 05:48 PM (UTC) by Terry

Message
Twisol said:

([1-9]?[0-9]|[12][0-9][0-9]|300)



Isn't that basically the same thing? I mean, I can change [1-2] to [12], and I will, but doesn't that only changes around what's already there? =\

Edit: In fact, it makes it larger :|
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #6 on Mon 14 Dec 2009 05:53 PM (UTC)

Amended on Mon 14 Dec 2009 05:56 PM (UTC) by Twisol

Message
Ah, you're right - I didn't look at the edit carefully enough. There is a small difference though:

Yours (shifted around a bit to look more like mine for the purposes of the example):
(300|[12][0-9][0-9]|\d{1,2})


Mine:
(300|[12][0-9][0-9]|[1-9]?[0-9])


It's exactly the same except for the last part, \d{1,2}. Yours will match 01, mine won't. Mine is strictly no-preceeding-spaces.

A shortened, preceeding-spaces-okay version would work like this though:
([0-2]?[0-9]?[0-9]|300)
or
([0-2]?\d?\d|300)



EDIT: Just figured I'd mention that, when breaking down numbers to match in a regex, I find it clearer to use [0-9] instead of \d, since I can visually see exactly what's going to be matched. Personal preference, really, but you can collapse the [0-9]'s back into \d's if you wanted.

EDIT 2: I prefer to use regexps for syntactic checking rather than semantic, to be honest. In this case I'd have just used \d+, and checked if it was between 0 and 300 in the script. Much simpler and clearer, IMO.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #7 on Mon 14 Dec 2009 06:29 PM (UTC)
Message
Yes, regular expressions are meant to be for syntax, not semantics. Think about what it means to capture a number between 0 and 300, using only syntax.

If the first digit is a 0, the string must terminate.
If the first digit is a 1 or a 2, it can optionally be followed by one or two digits.
If the first digit is a 3, it can optionally be followed by any one digit.
If the first digit is a 3 and the second digit is a 0, it can optionally be followed by a 0, or the string must terminate.
If the first digit is 4 or higher, it can optionally be followed by any one digit.

When you think about how relatively complex it is to express this even in English when you can only speak in terms of syntax, it starts to make sense why any regular expression will look cumbersome or unnatural.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #8 on Mon 14 Dec 2009 09:42 PM (UTC)
Message
Yes, I agree with both of these guys. Rather than a lengthy and fiddly regexp, since you are scripting anyway, just start your script with something like:


if range > 300 then return end


That clearly expresses your intentions, much more than a convoluted regexp would.

- 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.


24,588 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.