mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Aug 2004
Posts: 7,168
R
RusselB Offline OP
Hoopy frood
OP Offline
Hoopy frood
R
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
Code:
.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
H
Hoopy frood
Offline
Hoopy frood
H
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
Code:
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 confused

Joined: Dec 2002
Posts: 2,884
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,884
Code:
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
H
Hoopy frood
Offline
Hoopy frood
H
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 shocked crazy )

Joined: Aug 2004
Posts: 7,168
R
RusselB Offline OP
Hoopy frood
OP Offline
Hoopy frood
R
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
H
Hoopy frood
Offline
Hoopy frood
H
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 smile

e.g.:
Code:
; !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
S
Hoopy frood
Offline
Hoopy frood
S
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.


Link Copied to Clipboard