3

I need a pattern that will grab values for two or more parameters of varying length.

I need to convert a scanf format %i to a lua pattern and it is proving very difficult. I don't need to worry about the type of storage that can be passed in with scanf. Just the %i for integer and if they specify a specific link.

Documentation for scanf, if needed, can be found here.

This is what I have so far:

if(scanfLetter == "i" or scanfLetter == "d" or scanfLetter == "u") then
   if(specifiedNum == 0)then
     newPattern = "([%+%-]?%d+)"
   elseif(specifiedNum >= 2)then
     newPattern = "([%+%-%d]?%d^".. string.rep("%d?", specifiedNum-2)..")$"
   else
     newPattern = "(%d)"
   end

which basically just checks to see if they passed in a specific number or not (specifiedNum). If it is 0 that means they didn't.

It all works until there are two length specified %is in a row. For example:

%5i%6i

If they enter in 6 or more characters it works fine because match will return two values: the first one consisting of the first 5 numbers and the 6th goes the next value. The trouble is if there are fewer than 5. In scanf or printf it will not match %5i%6i if there are 5 or fewer numbers, but in my pattern it will still match under string.match and it returns all the values but the last in the first return and the second value get the last number entered.

More specific example so you don't have to type it all out and see it the pattern ends up looking like.

Given:

([%.%+%-%d]?%d[%.%d]?[%.%d]?[%.%d]?)([%.%+%-%d]?%d[%.%d]?[%.%d]?[%.%d]?[%.%d]?)

If 123456789 is passed to it, the match returns 2 values:

`12345` and `6789`

However, if 1234 is passed in, the match returns 2 values:

`123` and `4`

which is incorrect (it should not be a match).

Is what I seek possible?
(Maybe somebody has already written a scanf format to lua patterns converter?)

John Hascall
  • 9,176
  • 6
  • 48
  • 72
Birdbuster
  • 1,499
  • 1
  • 9
  • 13
  • Are you trying to write a `scanf`-equivalent in lua? – Etan Reisner Sep 08 '14 at 22:18
  • Are you using LuaJIT, or standard Lua? – kikito Sep 08 '14 at 22:26
  • That code snippet does not generate that sample pattern. That snippet generates `([%+%-%d]?%d^%d?%d?%d?)$` for `specifiedNum`==`5` and `([%+%-%d]?%d^%d?%d?%d?%d?)$` for `specifiedNum`==`6`. And, as a general statement, I wouldn't do both matches at the same time if possible, I'd transform lengths into simple counts and do type-checking afterwards. (Or go with translation to something like `lpeg`.) – Etan Reisner Sep 08 '14 at 22:29
  • You don't need to escape `.`, `-` and `+` inside character class. `[-+%d]` and `[.%d]` are enough (and neater). – hjpotter92 Sep 09 '14 at 01:01
  • Why'd are you doing this? You have hundreds of these format specifiers to translate from c to Lua? Why not create a Lua C extension module that calls scanf? Then you could just grep your source for scanf strings and give them to your function? – Oliver Sep 09 '14 at 02:34
  • @EtanReisner yes that is pretty much the plan for the most part. – Birdbuster Sep 09 '14 at 12:13
  • @Schollii Not very familier with lua any chance you could provide a link to to an example your talking about. Thanks – Birdbuster Sep 09 '14 at 12:15
  • @Birdbuster yes if Lua 5.1 then [writing and building a lua c extension module](http://hackmap.blogspot.ca/2010/04/writing-and-building-lua-c-extension.html) is easy to follow, and Lua's [BuildingModules](http://lua-users.org/wiki/BuildingModules) page might be useful for compile flags etc. But unless you are quite comfortable with C/C++ it probably will not be worth the effort. Again, if you state why you think you need scanf pattern matching, there might be other solutions, that will be within your reach. – Oliver Sep 09 '14 at 12:37
  • @Schollii Yes actually program in c/c++ daily where as the lua is totally new. Need the pattern matching because it is the route we thought could be done the quickest to create a string matching system that would invoke different things upon matching completely or not and storing what they passed in. I know it was 100% ideal but not having to worry about all of the scanf parts made it feel obtainable, but I'm not really conviced there is any logic that could recreate scanf functions into a single lua pattern because they just arnt the same and their priorities arnt the same. – Birdbuster Sep 09 '14 at 13:04
  • 2
    If you are comfortable with scanf patterns then you will have no problem becoming familiar with Lua's patterns. Drop scanf. You'll end up with code that is more robust. – Oliver Sep 09 '14 at 13:09
  • @Schollii Right I mean I like lua patterns and they are definately farm more powerful. Serve kinda almost different functionality. I guess big picture that I prob missed is that at the base I need something to compare strings passed in to patterns that are set up ahead of time. In lua I was using string.match in c we use vsscanf. Trouble is I have to support the old but we are moving forward into allowing users to use a lua api so we wanted to have the future use lua patterns but still needed to support the old and was hoping to just convert it to lua patterns internally,but dont think it pos. – Birdbuster Sep 09 '14 at 13:17

0 Answers0