0
votes

I want to do a pattern match on the table below. If there is a match, take the values of the 2nd and 3rd column as answer. The first column can have 1 or multiple patterns, row 5 has only 1 pattern to match against.

local pattern_matrix = {
  {{ "^small%-", "%-small%-",         },   "small",   50},    
  {{ "^medium%-", "%-medium%-",       },   "medium",  200},    
  {{ "^big%-", "%-big%-",             },   "big",     3},    
  {{ "^large%-", "%-large%-", "^L%-", },   "large",   42},             
  {{ "%-special%-",                   },   "special", 5},
}

i am using the following code to find the row that matches the input:

local function determine_row(name)
  for i = 1,#pattern_matrix,1 do
    for _,pattern in pairs(pattern_matrix[i][1]) do  --match against column 1
      if name:match(pattern) then 
        return i --match found in row i
      end
    end
  end
  return 0
end

the result should be

determine_row("itsamedium") = 2
determine_row("blaspecialdiscount") = 5
determine_row("nodatatomatch") = 0
1
What is the significance of the second column if you only want to return the third column as a result of the function? Also, I don't think you need the %- in %-small%- or %-medium%-, etc. If you're just matching the word 'small' in a larger word, the pattern small will work. - Allister

1 Answers

0
votes

You're code looks mostly right but the pattern you're using is a bit off. You're not getting the expected index because all the patterns expect hyphens around the words being matched. (due to %- in your pattern)

As Allister mentioned, if you want to match the sample input from your question you can just add that literal word to your list of patterns. Judging from your usage, you may even be able to simplify the pattern. For case insensitive search, use lower() or upper() on your input before matching.

For example:

<script src="https://github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js">
</script>

<script type='application/lua'>
local pattern_matrix =
{
  { "small",   50},
  { "medium",  200},
  { "big",     3},
  { "large",   42},
  { "special", 5},
}

local function determine_row(name)
  for i, row in ipairs(pattern_matrix) do
    if name:match(row[1]) then
      return i -- match found in row i
    end
  end
  return 0
end

local test_input = { "itsa-medium-", "itsBiG no hyphen", "bla-special-discount", "nodatatomatch" }

for _, each in ipairs(test_input) do
  print( each, determine_row(each:lower())  )
end
</script>