Thread Tools Display Modes
10-22-19, 11:50 AM   #1
Yukyuk
A Chromatic Dragonspawn
 
Yukyuk's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2015
Posts: 179
Pattern matching

I try to extract the itemId from a loot message but am not sure how to do this.

For example I have the following loot message.
"You receive loot: |cffffffff|Hitem:2589::::::::13:::::::|h[Linen Cloth]|h|r."

I use the this funtion to extract the number:
Lua Code:
  1. -------------------------------------------------------------------------------
  2. --  Extract the number from a message
  3. -------------------------------------------------------------------------------
  4. local CA_match_number
  5. local function ClassicAchievements_Match_number(line)
  6.     CA_match_number, = string.match(line,"%d+")
  7.     if CA_match_number ~= nil then
  8.         print(CA_match_number)
  9.         return(CA_match_number)
  10.     end
  11.     return(0)
  12. end

This will work just fine is the itemId is the biggest number in the message.
But it will fail if there is a bigger number in the message.

It there a way to extract the first number from a text string?
__________________
Better to fail then never have tried at all.
  Reply With Quote
10-22-19, 12:08 PM   #2
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 666
local _, _, itemID = strsplit(":", line)

This will split the message string by colons, making the item ID the third return in this message string. It gives you a string, so if you want a number:

itemID = tonumber(itemID)
  Reply With Quote
10-22-19, 12:14 PM   #3
Yukyuk
A Chromatic Dragonspawn
 
Yukyuk's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2015
Posts: 179
Perfect. Thank you Kanegasi
__________________
Better to fail then never have tried at all.
  Reply With Quote
10-22-19, 01:41 PM   #4
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
As a side note, the following line can be rewritten.
Code:
if CA_match_number ~= nil then
After the rewrite, it becomes
Code:
if CA_match_number then
The reason is that in Lua (possibly other languages as well) if/then checks seek a true answer or an answer with a value, meaning that if CA_match_number exists, it is therefore non-nil and not false.

Conversely, think about this line.
Code:
if not CA_match_number then
Specifying "not" means it must be either nil or false, and cannot be true; however, it can still have a value, in this case, the Boolean "false".

Taking it a step further, you can expand if/then to check for having a value, false, and nil.
Code:
if something then -- true or has a value, and not false and is non-nil
elseif something == false then -- specifically Boolean
elseif not something then -- non-value, non-Boolean
elseif something == nil then -- no value whatsoever
  Reply With Quote
10-22-19, 01:47 PM   #5
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
Follow up, to make things a bit more clear. The two following sets of lines are functionally identical but are not exactly identical.
Code:
if something then
if something == "cat" then
if something == 5 then
Code:
if not something then
if something == false then
if something == nil then
  Reply With Quote
10-22-19, 05:44 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Yukyuk View Post
This will work just fine is the itemId is the biggest number in the message.
But it will fail if there is a bigger number in the message.

It there a way to extract the first number from a text string?
Lua always returns the first match in a string. The problem with this is since the color code for the string is a hex value, it can contain numeric characters, which will sometimes get captured instead depending on the item quality. You can further define what to grab by defining the pattern better.
Code:
return tonumber(line:match("|Hitem:(%d+)")) or 0;
Notes: The parenthesis define what to capture in a pattern. This defaults to the entire pattern if no captures are defined. Also, this is a shortcut way to use string.match() since the string table is set as the metatable for all strings. string.match() also returns strings exclusively if not nil. tonumber() converts this into a number and will pass nil through. or handles the next step by providing a default value if nil is passed through. Lastly, return is not a function, it's part of the language structure. It'll lead to some confusion further down the road if you write it like a function call.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Pattern matching

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off