|
Joined: Aug 2004
Posts: 7,252
Hoopy frood
|
OP
Hoopy frood
Joined: Aug 2004
Posts: 7,252 |
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 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.
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
You missed a couple of things and that may be the culprit. if ($regex(ip,$3-,/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g) > 0) { This will match any IP addresses: on *:TEXT:*:#: {
if ($regex($1-,/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g)) echo -a $regml(1)
}
Last edited by Tomao; 25/02/09 09:18 AM.
|
|
|
|
Joined: Feb 2007
Posts: 75
Babel fish
|
Babel fish
Joined: Feb 2007
Posts: 75 |
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: 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: if ($regex(ip,$3-,(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))) { Hope this helps 
Last edited by Trixar_za; 25/02/09 11:53 PM.
GigIRC Network Admin irc.gigirc.com
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
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.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
...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):
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) 
|
|
|
|
Joined: Aug 2004
Posts: 7,252
Hoopy frood
|
OP
Hoopy frood
Joined: Aug 2004
Posts: 7,252 |
Thanks to all. I knew I was close.
|
|
|
|
Joined: Feb 2007
Posts: 75
Babel fish
|
Babel fish
Joined: Feb 2007
Posts: 75 |
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  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.
GigIRC Network Admin irc.gigirc.com
|
|
|
|
Joined: Oct 2005
Posts: 1,741
Hoopy frood
|
Hoopy frood
Joined: Oct 2005
Posts: 1,741 |
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
|
|
|
|
Joined: Feb 2007
Posts: 75
Babel fish
|
Babel fish
Joined: Feb 2007
Posts: 75 |
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 
GigIRC Network Admin irc.gigirc.com
|
|
|
|
|