mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Aug 2004
Posts: 7,252
R
RusselB Offline OP
Hoopy frood
OP Offline
Hoopy frood
R
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
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,559
H
Hoopy frood
Offline
Hoopy frood
H
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
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,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
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.


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
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 shocked crazy )

Joined: Aug 2004
Posts: 7,252
R
RusselB Offline OP
Hoopy frood
OP Offline
Hoopy frood
R
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
H
Hoopy frood
Offline
Hoopy frood
H
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 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,962
S
Hoopy frood
Offline
Hoopy frood
S
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.

Link Copied to Clipboard