How to data match characters?

I have data coming into vera. The data length is not fixed. Data can be numbers or characters. I want to see if the data I receive contains specific letters or numbers at specific locations.

The data could be
abXXcdefghijklmnopqrs
or
abXXcdefghijk
or
abXXcdefYYghijklkjdlkfjslkdfjlskj
or
abXcdeYfZhi1jkl234mnop

  1. How do I check the data to see if XX is the third and forth characters and ignore everything after? examples 1 and 2 above.
  2. How do I check the data to see if XX is the third and forth characters and YY is the tenth and eleventh characters and ignore everything after? example 3.
  3. The answers above will probably answer this but how would I confirm X, Y, Z, 1, 2, 3, 4 are in the proper place in example 4?

I’m hoping for some syntax such as if data = (**XX(IgnoreTheRest)), if data = (**XX****YY(IgnoretheRest)), and if data = (ignoretill X ignoretill Y ignoretill Z ignoretill 1…)

I’ve scoured various plugin and see “data:match” being used but I haven’t found a plugin that is concise enough to understand. Those that I found call multiple functions to process data and I get lost trying process/retain all of the logic in my head.

Thanks in advance.

local s = "abXXcdefYYghijklkjdlkfjslkdfjlskj" local t = "abXcdeYfZhi1jkl234mnop" if (s:match("^..XX....YY") and t:match("X.*Y.*Z.*1.*2.*3.*4")) then -- Successful match end

Dot matches any one character. Dot-star matches any number of characters, including none. Caret matches the beginning of the string. Dollar matches the end of the string. Alphanumeric characters match only themselves.

Notice how you can acheive “ignoretherest” by omitting the dollar in the pattern.

Lua reference for patterns: Lua 5.1 Reference Manual

Most programming languages provide pattern matching using what’s called regular expressions.
LUA does not have a true regular expression library … but it’s close.

Regular Expressions can be very simple to very complex … even someone that knows the syntax can look at a pattern and wonder what it’s trying to accomplish.

Consider it another programming language and read about their use, nuances, and limitations to use them correctly.

Thanks futzle/Richard. One more roadblock cleared.

How would I got about extracting the desired characters and then create a variable from it?

Say I have
data = abcdXXdef
I use the if statement futzle provided to confirm it contains data that I want. Now I want to take that part of the data and create a variable of it and discard the rest.

So for example (assuming I already confirmed it contains the info I want):

data = abcd99def – I want to extract 99 and make a variable of it
local datanew = tostring(data(^… “**”)) – this is where I’m making things up
print datanew – magically 99 gets printed

Likewise I want to do the reverse. I think this is correct but want to confirm.

mydata = 98
local mydatanew = (“abcd” … mydata … “def”)
print mydatanew – abcd98def gets printed

That’s what groups are for in Regular Expressions … a group is typically delimited by parenthesis.
Regular Expressions are so sophisticated they have a whole forum on just that topic:
See: [url=http://regexadvice.com/forums/]http://regexadvice.com/forums/[/url]

A general discussion of these is outside the scope of the MCV forums.

Thanks Richard. I am a bit discouraged. Learning regular expressions seems like it will take a solid investment of time. Maybe my question complicated things beyond what im trying to do.

The placement of the data that I want is fixed so hopefully this simplifies things. Is it possible to accomplish what is below without needing to learn regular expressions?

Here is a boiled down example. Incoming data is

t1Axxxxxxxxxx
I know the first place will be a letter than can be ignored (t)
The second place is a number that can be ignored (1)
The third can be a number or letter and I want to save that as a variable (A)
everything after that ignored

Is there no easy way to take the incoming data, select whatever is in the third place, and save it as a variable?

Forgive me if I’m asking the same question that you have already answered but I think I may have overly complicated things with my previous question. I believe there are commands that can take a word and save each letter as separate variables.

Such as: – all syntax invented

x=cat
SOME FUNCTION(x) that saves things into a table/array/etc called “a”
so
a1=c
a2=a
a3=t

then if I wanted to keep just what is in the third place it would be variable a3. If I wanted to save what was in places 2 and 3, I could combine a2 and a3 to make a new variable

local new = a2…a3

Thanks.

found = string.match(InputData, “^%a%d([%a%d])”)
if (found) then

end

The variable InputData contains the data you want to analyze
If the criteria are matched … found will contain the selected character.
This will do what you asked … but it’s not intuitive … and outside the scope of this forum to explain it …
And if there are data other than letters and numbers (like space, tabs, punctuation, … it will not work … but you did not specify that! That would be a different regular expression.

Thanks for the help Richard. Apologies for not being clear. I’m attempting to self-teach and have no previous programming experience. If you take a look at my plugin once it is done, I’m sure it will be quite apparent. Think Rube Goldberg with duct tape.

Plugging on.

If you’re extracting data from strings, lookup the Lua construct called a Capture. They’re referenced extensively in the reference manual section on Patterns:
Lua 5.1 Reference Manual

They’re also used extensively in plugins like Weather, Brultech, etc over on http://code.mios.com.

Some of those examples can be quite complex (Weather) since the underlying string is complex, but others (like the Brultech stuff) are fairly simple.

Like this one we use for finding : in IP Addresses:
http://code.mios.com/trac/mios_brultech-power-monitor/browser/trunk/L_BrultechMeter1.lua#L165

Sometimes it’ll be easier to look at these examples, and refer back to the man page.

You’ll also find this site useful, esp their tutorials:
lua-users wiki: Patterns Tutorial

which you can test using a Windows/Mac/Linux installed version of Lua (without the pain of doing it on Vera)

Thanks All. Learning a lot.

I understand that when I use this:

found = string.match(InputData, "^%a%d([%a%d])") if (found) then .... end
found = whatever the next character is after after the first letter+number combination is found.

I attempted to modify this to return whatever the next 2or3 characters were after the match but wasn’t having much luck. I don’t understand the role of ([%a%d]) and couldn’t find a suitable explanation online. I recognize the explanation isn’t simple and therefore best gained through proper study of lua on my part.

So I gave up on that but found string.sub and came up with this.

local data = “t1Axxxxxxxxxx”
local found = string.sub(data, 3, 3)
luup.io.write("found is "…found)

Seems to work and I can modify 3,3 to extract other sections. Any downsides/limitations of using this?

Still plugging.

string.sub() is perfectly good. Sometimes a problem suits itself more to using string.sub, and sometimes it suits itself to string.match. Often, it comes down to whatever the developer is most comfortable using.

Square brackets work like this in a pattern: [01] matches any one character, only a 0 or a 1. If there’s any other character at that point in the string then the match fails. To match any one digit you would say [0123456789]. That’s common enough there is a shorthand: %d (think d for decimal). Likewise [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ] matches any one letter, and there’s a shorthand for that too: %a (a for alphabetic). [%d%a] matches anything that is either a letter or a digit.

In your case … string sub will always extract the 3rd character … independent of what character 1 and 2 are. You indicated that the first character had to be a letter and the second a digit.

 t3XYZ   Would match an X
 3tXYZ   Would not match

If you always just take the 3rd character it will match both string with a match of X.

So it’s a matter of you want.

[%a%d] Will match any letter or number