|
Joined: Aug 2004
Posts: 7,168
Hoopy frood
|
OP
Hoopy frood
Joined: Aug 2004
Posts: 7,168 |
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,552
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,552 |
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,884
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,884 |
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.
|
|
|
|
Joined: Nov 2006
Posts: 1,552
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,552 |
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,168
Hoopy frood
|
OP
Hoopy frood
Joined: Aug 2004
Posts: 7,168 |
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,552
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,552 |
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,884
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,884 |
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.
|
|
|
|
|