|
Joined: Aug 2004
Posts: 7,252
Hoopy frood
|
OP
Hoopy frood
Joined: Aug 2004
Posts: 7,252 |
Eg: !add Rome, "Saudi Arabia", Sweden black pistol, machine gun When this line is processed, it would do the equivalent of .hadd -m Items Rome $addtok($hget(Items,Rome),black pistol,44)
.hadd -m Items Saudi_Arabia $addtok($hget(Items,Saudi_Arabia),black pistol,44)
.hadd -m Items Sweden $addtok($hget(Items,Sweden),black pistol,44)
.hadd -m Items Rome $addtok($hget(Items,Rome),machine gun,44)
.hadd -m Items Saudi_Arabia $addtok($hget(Items,Saudi_Arabia),machine gun,44)
.hadd -m Items Sweden $addtok($hget(Items,Sweden),machine gun,44) Where I'm having trouble is separating the different locations from each other and the items from, not only each other, but also the locations. The locations will be a single name or will be enclosed in quotation marks. I've tried various ideas using /tokenize and while the usage of 34 is close, it's still not correct, as I won't know in advance which (if any) of the locations will be in quotation marks, or even if there will be more than one location. Minimum entry consists of a location and an item.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
Hum, the current syntax of !add is imho hard to follow/comprehend. I think changing the syntax would be preferable: "locations" and "items" separated by a distinct char like an "=". But I assume that's no option for you. The following routine may do the job. Assuming: - location(s) and item(s) are separated by the first space char, as long this space char is not inside a quote (therefore the use of quotes at all :D) - multiple locations are separated by a comma char, likewise multiple items alias addtest {
var %string = Rome, "Saudi Arabia", Sweden black pistol, machine gun
var %n = 1, %locations, %items
; loop comma-delimited tokens, tokenize the token
while ($gettok(%string,%n,44)) {
var %token = $v1
tokenize 32 %token
; looping "locations" so far
if (!%items) {
; token is no quote, and token contains a space char: split token found.
if (%token == $noqt(%token)) && ($2) {
; first part of split token belongs to "locations", second part to "items"
var %locations = $addtok(%locations,$1,44)
var %items = $2-
}
; it's not yet the split token: add this token to "locations" and remove possible quotes
else { var %locations = $addtok(%locations,$noqt($1-),44) }
}
; already looping "items": add this token to "items"
else { var %items = $addtok(%items,$1-,44) }
inc %n
}
ECHO -a locations: %locations
ECHO -a items: %items
} ... just the first thing that came to my mind. There's always a better way to do it
|
|
|
|
Joined: Dec 2002
Posts: 2,962
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,962 |
split_text {
; Usage: /split_text <formatted string>
; eg. /split_text Rome, "Saudi Arabia", Sweden black pistol, machine gun
var %input = $regsubex($1-, /\s*\x2c\s*/g, $chr(44))
%input = $regsubex(%input, /(?<=^|\x2c)(?:(\w+)|"([^"]+)")\s+([^\x2c]+)/, $+(\1,$cr,\2))
var %cities = $gettok(%input, 1, 13), %weapons = $gettok(%input, 2, 13), %weapon
var %i = $numtok(%cities, 44), %weaponcount = $numtok(%weapons, 44), %city
while %i {
%city = $replace($noqt($gettok(%cities, %i, 44)), $chr(32), _)
%j = 1
while %j <= %weaponcount {
%weapon = $gettok(%weapons, %j, 44)
.hadd -m Items %city $addtok($hget(Items, %city), %weapon, 44)
inc %j
}
dec %i
}
} You should really change the format of the message if at all possible. It's needlessly difficult to parse for computers and humans.
Spelling mistakes, grammatical errors, and stupid comments are intentional.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
Err, my code will break if the "splitting token" contains a quote, e.g: %string = Ohio, Pennsylvania, "West Virginia" cars, monster trucks The approach of starbucks_mafia seems to have no flaw (and I'm still trying to figure it out  )
|
|
|
|
Joined: Aug 2004
Posts: 7,252
Hoopy frood
|
OP
Hoopy frood
Joined: Aug 2004
Posts: 7,252 |
Changing the format is possible, but I also wanted a format that would be easy for a person to enter, and since commas and spaces are (probably) the most common separators used when typing a message, I went with them.
Any suggestions as to another format that would be easier for the computer to interpret and still easy for a human to enter?
The format must allow for multiple locations and multiple items, with a space being a valid character in a location name.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
For example !add location1, location 2, location X : item1, item 2, item x ...would only require some gettok and while  e.g.: ; !add <locations separated by comma> : <items separated by comma>
; (the $gettok($v1,1-,32) will remove leading/trailing spaces of locations/items)
on *:text:!add *:#: {
tokenize 58 $2-
var %n = 1
while ($gettok($1,%n,44)) {
var %location = $replace($gettok($v1,1-,32),$chr(32),_), %x = 1
while ($gettok($$2-,%x,44)) {
hadd -m items %location $addtok($hget(items,%location),$gettok($v1,1-,32),44)
inc %x
}
inc %n
}
}
Last edited by Horstl; 15/03/09 06:11 AM.
|
|
|
|
Joined: Dec 2002
Posts: 2,962
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,962 |
As Horstl said, adding an additional separator between the cities and the weapons makes it a lot easier to parse for a computer (the entire second regex in my code was merely to find and insert a carriage-return character there to be used as a token delimiter). It also makes it easier to read for humans I think.
Spelling mistakes, grammatical errors, and stupid comments are intentional.
|
|
|
|
|