|
Joined: Mar 2009
Posts: 74
Babel fish
|
OP
Babel fish
Joined: Mar 2009
Posts: 74 |
on 1:Text:!calc *:*: {
if ($isOnExceptionList($chan)) { halt }
if ($flood) { halt }
if ($evilreply) { halt }
msg # Calc: $2- = $calc($2-)
} I suspect regex is the best way to help with this, but I don't know how to use regex for this. Reading through information regarding regex I still haven't found what I'm after. I'm looking for a way to take the $2-, and have it find every mathematical operator, change it to the appropriate identifier ( deleting all instances of the $ character before doing creating the identifiers), then evaluate the string with $eval prior to using $calc on it. It needs to only match identifiers used for math, or those that I specify if I make custom ones, so as to prevent a type of exploit that would allow a person to run commands I don't want just anyone running ( no tricks with $quit or the like). Anyone know how to set this up? By the way, you can ignore the first 3 lines in the On Text trigger. The first one prevents the script from running in channels where people don't want scripts running, the second one just makes sure I don't get flooded with requests, and the third one is a joke thing I can enable for laughs. The order is intentional, so I don't plan on putting them in the same line. Edit: I created something with some help in a chat, but it doesn't seem to work. alias -l makeIdentifiers {
var %arg $remove($1-,$chr(36))
var %regexIdentifierMatch \b[A-Za-z]+\(
var %matches $regex(Identifiers,%arg,%regexIdentifierMatch)
echo -s Matches: $+ %matches
var %a 1
while (%a <= %matches) {
var %match $regml(Identifiers,%a)
echo -s Match: $+ %match
if ($istok($identifierList,%match,44)) {
var %arg $replace(%arg,%match,$chr(32) $+ $chr(36) $+ %match)
}
inc %a
}
return %arg
}
The first echo says one value was matched, but the second echo is blank, it shows Match:, but not the matched value. The string passed through it was ceil(2.5). It seems $regml is returning $null.
Last edited by KageNoOni; 29/05/10 01:39 AM.
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
By the way, you can ignore the first 3 lines in the On Text trigger. Well, you could have done it as: on 1:Text:!calc *:*: {
if ((!$isOnExceptionList($chan)) && (!$flood) && (!$evilreply)) {
msg # Calc: $2- = $calc($2-)
} I'm looking for a way to take the $2-, and have it find every mathematical operator, change it to the appropriate identifier (deleting all instances of the $ character before doing creating the identifiers) Sounds like you should be able to use $regsubex and $replace for this operation.
|
|
|
|
Joined: Mar 2009
Posts: 74
Babel fish
|
OP
Babel fish
Joined: Mar 2009
Posts: 74 |
I need it to stop checking further if any of them evaluate to true. The second one manipulates variables, and the third one actually sends a message to a chat (if the third one evaluates to true), this is why I keep them seperate.
The reason I don't use $regsubex is the risk of evaluating identifiers I don't want evaluated. This is why I was using $regml, but it is returning $null instead of the matches found by $regex.
|
|
|
|
Joined: Mar 2009
Posts: 74
Babel fish
|
OP
Babel fish
Joined: Mar 2009
Posts: 74 |
Looks like I just needed an extra set of parenthesis in the $regex, it works now. Edit: It seems to only be finding the first match, but nothing after that. Any idea why it can't seem to find more than one match when I run this? alias -l makeIdentifiers {
var %arg $remove($1-,$chr(36),$chr(37))
var %regexIdentifierMatch ([A-Za-z]+\()
var %matches $regex(Identifiers,%arg,%regexIdentifierMatch)
echo -s Matches: $+ %matches
var %a 1
while (%a <= %matches) {
var %match $regml(Identifiers,%a)
echo -s Match: $+ %match
if ($istok($identifierList,%match,44)) {
var %arg $replace(%arg,%match,$chr(32) $+ $chr(36) $+ %match)
}
inc %a
}
return %arg
} Matches:1 Match:int( Calculating $int(2.5) + abs(-3). Matches:1 Match:abs( Calculating $abs(-3) + int(2.5)
Last edited by KageNoOni; 29/05/10 09:02 AM.
|
|
|
|
Joined: Aug 2004
Posts: 7,252
Hoopy frood
|
Hoopy frood
Joined: Aug 2004
Posts: 7,252 |
You need the /g switch in your regex for it to recognize more than just the first match. My knowledge of regex is minimal, but that is the switch you are missing.
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
RusselB is right. You need the /g modifier to make regex greedy in searching for the match globally.
|
|
|
|
Joined: Aug 2006
Posts: 183
Vogon poet
|
Vogon poet
Joined: Aug 2006
Posts: 183 |
RusselB is right. You need the /g modifier to make regex greedy in searching for the match globally. /g is actually for "global". Greedy is for repetition in regex. http://www.regular-expressions.info/repeat.htmlEdit: Never mind. Reading comprehension failure.
Last edited by Thrull; 30/05/10 01:43 AM.
Yar
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
Right. I was meaning to say it as global...hence I noted "globally." at the end of my sentence.
The /g modifier can sometimes be mistaken for greedy mode in regex...because of the "g"
|
|
|
|
Joined: Mar 2009
Posts: 74
Babel fish
|
OP
Babel fish
Joined: Mar 2009
Posts: 74 |
Odd, all the info I could find on regex never mentioned anything about this /g switch.
/([A-Za-z]+\(\))/g
To enhance my understanding of Regex, what are the parts I put in red for? Why did you add a / to the front? I have no idea what this would do. Escaping the ) in the original regex I put up doesn't really help me, as I don't want to search for a literal end parenthesis, so why is it escaped here? My goal was to find a string of letters, followed by (, and that's all the match I was after. Also, why the second parenthesis at the end? My guess regarding the last 2 is to have it search for the ), which I don't want matched, and if that's the case, I can probably remove them, but it still doesn't explain the / at the beginning of this one.
|
|
|
|
Joined: Mar 2009
Posts: 74
Babel fish
|
OP
Babel fish
Joined: Mar 2009
Posts: 74 |
Ok, I took out the second 2 red characters, and put that in my regex match, and it works beautifully so far. Thanks for the help, but I would like to learn more about regex, as I can really see the power behind the tool. So if I could get the questions above answered it would be very helpful.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
/([A-Za-z]+\(\)) /g They are delimiters - to delimit your string from the modifiers/switches like "g" for global, "S" for strip, or "i" for case-insensitive. You need to know that if an expression starts with the "m" char, the next char will be used as the delimiter. The "/" char is the "default" delimiter, and does not require the leading "m". Any char can be used as a delimiter: "m/test/g" is the same as "/test/g" or "m@test@g". And if you want to match the delimiter literally, you have to escape it of course. Delimiters aren't required all the time, but it's a good habit to always put them: While $regex(go test me,test) will do the same as $regex(go test me,/test/), $regex(surround,mono) will find a match - to some people's surprise - as it uses the "o"'s of "mono" as delimiter, thus matches like $regex(surround,m/n/) - which is the same as $regex(surround,n). Here is more info about it.
|
|
|
|
Joined: Mar 2009
Posts: 74
Babel fish
|
OP
Babel fish
Joined: Mar 2009
Posts: 74 |
Thanks for the link, it's a great help.
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
The /S (capital letter s) modifier, I believe, is solely for mIRC to strip control codes.
|
|
|
|
|