mIRC Homepage
Posted By: RusselB regex query - 25/02/09 05:54 AM
I'm trying to get an IP address that is posted as part of a message in a channel. The address will be in $3- but I don't know exactly where.
I thought the following would work, but testing keeps bringing up an insufficient parameters message.
Here's the line that is being referred to
Code:
if ($regex(ip,$3-,\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) > 0) {
I admit I'm trying to learn about regex, but I'm unable to determine what is missing.

A correction and explanation of the correction would be appreciated.
Posted By: Tomao Re: regex query - 25/02/09 06:48 AM
You missed a couple of things and that may be the culprit.
Quote:
if ($regex(ip,$3-,/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g) > 0) {


This will match any IP addresses:
Code:
on *:TEXT:*:#: {
  if ($regex($1-,/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g)) echo -a $regml(1)
}
Posted By: Trixar_za Re: regex query - 25/02/09 11:43 PM
You don't actually need the greedy paramater /g (although it's 'good practice' to enclose a regex between two /).

For example, this will work just as fine too:
Code:
alias testregex {
  echo True/False: $regex(ip,$ip,(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))
  echo Return: $regml(ip)
}

Basically, I just enclosed the regex between (), so all you really needed was to enclose it either in () or /'s. The reason you need them at the start and end of your regex is because of the comma in {1,3}, which the $regex identifier assumes is the start of ANOTHER parameter after comma.

Here is your code so it will work:
Code:
if ($regex(ip,$3-,(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))) {

Hope this helps wink
Posted By: Tomao Re: regex query - 26/02/09 12:08 AM
From what I learn of regular expressions, I never heard of the term "greedy," but rather: The g means global search flag that makes the search for regex pattern throughout the string, creating an array of all occurrences it can find matching the given pattern. And yes, it will work with or without it in the regex string RusselB has provided.
Posted By: Horstl Re: regex query - 26/02/09 12:44 AM
...or - if you don't want to capture at all - put the expression-with-commas in a variable and use $regex([name],text,%expression)

Another secondary note:
if you want to match valid IPs a bit more reliable (e.g. no match on 355.1.2.3) you may use this expression (I didn't write it):
Code:
var %reg = /\b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\b/
if ($regex(ip,$3-,%reg)) { echo -ag first IP match: $regml(ip,1) }
(no need to put this one into a var, just a matter of preference) smile
Posted By: RusselB Re: regex query - 26/02/09 04:09 AM
Thanks to all. I knew I was close.
Posted By: Trixar_za Re: regex query - 26/02/09 12:54 PM
True, could mean global as well, because it keeps searching for more matches after it made the first one - I got the name from a mIRC regex tutorials, so it kind of stuck with me :P. I found that if you use it with too many regex checks, it tends to slow down the script a bit, especially with sockets and complex regexes (as I found out with my own mudclient script).

Generally, I avoid using /g unless I want to make large substitutions where I expect the match to be in large chunks of the data, but for a simple if match it tends to work well without it (and a little faster). I also tend to use iswm to match and $regsubex to change where I can, but then again, it's just my personal preferences wink

Thanks for pointing out that you could set it to variable @ Horstl. It's generally the best when your trying to avoid syntax errors like the comma causes when in your regex.
Posted By: genius_at_work Re: regex query - 26/02/09 02:59 PM
The /g always means global. It means that the regex engine tries to match your regex as many times as possible within the text you are searching. It starts searching again at the next character after the last character that was used for the previous match. For example, if you have this text:

ABCDEABCDEABCDE

This non-global expression:

/C/

Would return a 1 to indicate that your regex matches somewhere in the searched text.

But, this global expression:

/C/g

Would return a 3 to indicate that your regex matched 3 times in the searched text.



Greedy is another term in regex that means the regex engine tries to take as many characters as it can, while still matching your regex. The regex engine can also run in non-greedy mode, where it takes as few characters as possible while still matching your regex. For example, if you had this text:

ABCDEABCDEABCDE

And you used this greedy regex:

/(B.*D)/

You should get this result:

BCDEABCDEABCD

But, if you used this non-greedy regex:

/(B.*?D)/

You should get this result:

BCD


-genius_at_work

Posted By: Trixar_za Re: regex query - 26/02/09 09:15 PM
Thanks for the clarification genius. I think I got confused with the term greedy and global. I think I grouped them because they went for more than a single match (in characters and matches returned). Mind you, I still avoiding using overly greedy regexes and I find myself avoiding to use * at all. Which, for those that don't know, is unlike the wildcard *, because means zero or more matches, which can be BAD with some regexes, because depending on how you wrote, it can pretty much match any and everything. I find using .+ works better for times like that smile
© mIRC Discussion Forums