Table Help

Posted by Siris on Fri 03 Sep 2010 12:04 AM — 11 posts, 44,051 views.

#0
Here we go, i think i'm in over my head with this one. I would like to take a list of items, add them to a table and then autobuy them when i get a list from a shop that has said items in stock.

<triggers>
<trigger
enabled="y"
match="^Phase .\: Recover ((?i)an|a) (.*?)\.$"
regexp="y"
send_to="12"
sequence="100"
>
<send>Items["%2"]=true




</send>
</trigger>
</triggers>

matches my item addition trigger just fine, witch looks like this:
Phase 1: Recover a glass of mead.
Phase 2: Recover a bottle of Beltane red beer.
ect.

now my shop list looks like this:
No. Item Name Level Amount Price
1) A quill pen 6 No limit [ 90 gp]
2) A page of parchment 6 No limit [ 50 gp]
3) A postage stamp 5 No limit [ 130 gp]
4) A stamp collector's book 10 261 [ 25,000 gp]
5) A page of vellum 6 0/1 [ 60,000/3,999 gp]

the trigger that i was working on to match the shop list looks like this:

<triggers>
<trigger
enabled="y"
match="^ \d\) (.*?) /s {1,31} /d"
regexp="y"
send_to="12"
sequence="100"
>
<send>Note ("%1 %2 %3 %4 %5")
if Items["%2"] then -- check item name for match in table
Send ("buy '" .. "%1" .. "'")
end -- if
</send>
</trigger>
</triggers>
but i cannot get it to match with my limited knowledge of expessions in lua, any suggestions?
Amended on Fri 03 Sep 2010 12:07 AM by Siris
Australia Forum Administrator #1
You need to get your slashes right for a start.

/d is just /d, to match digits you want \d and if you want more than one (as in 50 gp) you want \d+


Template:regexp
Regular expressions
  • Regular expressions (as used in triggers and aliases) are documented on the Regular expression tips forum page.
  • Also see how Lua string matching patterns work, as documented on the Lua string.find page.
Australia Forum Administrator #2
Also help us please by using code tags, so you list looks like this:



now my shop list looks like this:
No.  Item Name                     Level  Amount   Price
  1) A quill pen                    6     No limit       [             90 gp]
  2) A page of parchment            6     No limit       [             50 gp]
  3) A postage stamp                5     No limit       [            130 gp]
  4) A stamp collector's book       10    261            [         25,000 gp]
  5) A page of vellum               6     0/1            [   60,000/3,999 gp]


Template:codetag
To make your code more readable please use [code] tags as described here.
#3
My Apologies sir, the first /d was an oversight on my part. What I'm really wondering is how to get the shoplist trigger to match. I need to pull the first number on the list for the buy command, and I need to match the string pulled from my table.
Australia Forum Administrator #4
OK, well testing with your data, and then doing a:


require "tprint"

tprint (Items)


reveals this:


"glass of mead"=true
"bottle of Beltane red beer"=true


Your first problem seems to me that the shop sells "A page of parchment", not "page of parchment" so unless things look differently for "glass of mead" you need a partial match.

What you can do, for each line from the shop, is check your entire list. eg.


for item in pairs (Items) do
  if string.match ("%2", item) then
    Send ("Buy '%2'")
    break   -- found it, exit loop
  end -- if found
end -- for


Something like that should do it.
#5
How would I get the trigger to match on:

No.  Item Name                     Level  Amount (Sell/Buy)  Price (Sell/Buy)
  1) a bottle of Beltane red beer   6     No limit       [             90 gp]


What I'm confused about is what wildcards would I have to use to do a partial match of that string while retaining the item number and item description so they can be passed into the script.
Australia Forum Administrator #6
Well if the table is always that size (and I don't know that for sure) you can use exact sizes, eg.



^([ 0-9]{3})\) (.{30}) 


That is 3 characters (numbers or spaces), a RH bracket, a space, and then 30 characters (the item name). The item number is the first wildcard, and the item name is the second.

By not putting in a trailing $ it doesn't care what the rest of the line is.
Amended on Fri 03 Sep 2010 06:44 AM by Nick Gammon
#7
As always your a gentleman and a scholar my good sir. So puting a number in between two '{30}' denotes string match length? I was thinking I would have to use [1,30] to match 30 spaces. Either way, thank's again for your fast response and knowledge.
Netherlands #8
In regular expressions, you need to think of the different parts as 'matching' parts and quantifier parts. The quantifier applies to the matching part that is directly before it.

a* means: zero or more instances of the letter a
a+ means: one or more instances of the letter a
a? means: zero or one instances of the letter a
a{0,1} means: zero or one instances of the letter a (right, the ? is a shorthand for this one)
a{1,10} means: between 1 and 30 instances of the letter a (could write this out as aa?a?a?a?a?a?a?a?a?)
a{10} means: exactly 10 instances of the letter a (one could write this out full like aaaaaaaaaa)

Of course, rather than a letter a, you could have more complicated matching parts put within groups that are repeated such as ^(\w+:\d+\s*)+$, which might match on something like 'HP:123 Mana:345 psi:7'.

Hope that clears it up a bit for you.
#9
Everything works beautifully except for this:


Phase 1: Recover a pair of leather boots.

No.  Item Name                         Level  Amount       Cost
  3) A pair of leather boots            15    24           [      6,375 gp]


It will not match if the case is different, is there any way to make these two triggers non-case subjective?


<triggers>
  <trigger
   enabled="y"
   group="QuestBot"
   ignore_case="y"
   keep_evaluating="y"
   match="^Phase .\: Recover (.*?)\.$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>Items["%1"]=true
require "tprint" -- In here for Debug
tprint (Items) -- In here for Debug
</send>
  </trigger>
</triggers>

And

<triggers>
  <trigger
   enabled="y"
   group="QuestBot"
   ignore_case="y"
   match="^([ 0-9]{3})\) (.*?) [ 0-9]"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>Note {"Matched on %1 - %2"} -- In here for Debug
  for item in pairs (Items) do
  if string.match ("%2", item) then
    Send ("Buy %1")
    break   -- found it, exit loop
  end -- if found
end -- for

</send>
  </trigger>
</triggers>


Any ideas?
Australia Forum Administrator #10
Look up the string functions all sorts of things are possible. For example change the match line to:


if string.match (string.lower ("%2"), string.lower (item)) then


By forcing both to lower-case you effectively make it case-insensitive.

However you are probably better off using string.find because that lets you do a "simple" find, and in this case the thing you are looking for is not a regular expression.

eg.


if string.find (string.lower ("%2"), string.lower (item), 1, true) then