Как разобрать серию строк с пробелами между ними в Lua

#parsing #lua

#синтаксический анализ #lua

Вопрос:

Я пытаюсь проанализировать текстовый файл, который находится в формате имени хоста, IP mac-адреса в Lua. Все три разделены пробелами, чтобы попытаться затем сохранить это в таблице, используя Lua.

Я пытался сделать это с помощью функции:match, но не вижу, как заставить ее работать.

 function parse_input_from_file()
  array ={}
  file = io.open("test.txt","r")
  for line in file:lines() do
    local hostname, ip, mac = line:match("(%S ):(%S ):(%S )")
    local client = {hostname, ip, mac}
  table.insert(array, client)
  print(array[1])
  end
end
  

Он продолжает печатать местоположение в памяти, где хранится каждый ключ / значение (я думаю).

Я уверен, что это относительно простое решение, но, похоже, я его не вижу.

Комментарии:

1. вы говорите, что пробелы — это разделитель, тогда: line:match("(. )%s (. )%s (. )")

Ответ №1:

Если имя хоста, ip и mac разделены пробелом, ваш шаблон может не использовать двоеточия. Я добавил несколько изменений для сохранения записей в клиентской таблице.

 function parse_input_from_file()
  local clients ={}
  local file = io.open("test.txt","r")
  for line in file:lines() do
    local client = {}
    client.hostname, client.ip, client.mac = line:match("(%S ) (%S ) (%S )")
    table.insert(clients, client)
  end
  return clients
end

for i,client in ipairs(parse_input_from_file()) do
   print(string.format("Client %d: %q %s %s", i, client.hostname, client.ip, client.mac))
end
  

В качестве альтернативы:

 local client = table.unpack(line:match("(%S ) (%S ) (%S )"))
  

тогда hostname есть client[1] что не очень интуитивно.

Ответ №2:

В регулярном выражении нет двоеточия:

 local sampleLine = "localhost 127.0.0.1 mac123"
local hostname, ip, mac = sampleLine:match("(%S ) (%S ) (%S )")
print(hostname, ip, mac) -- localhost 127.0.0.1 mac123
  

Комментарии:

1. Это великолепно — я знал, что это что-то столь же тривиальное, как это. Вы знаете, как я могу сохранить это в массиве / таблице. Итак, если бы у меня было две примерные строки, он мог бы хранить список, а внутри списка таблицу?

2. @Syn создайте локальную таблицу для каждой строки local tab = {} tab.hostName, tab.ip, tab.mac = sampleLinie:match("(%S ) (%S ) (%S )") и поместите их в другую таблицу. если вас не волнуют строковые ключи, вы также можете использовать local tab = table.pack(sampleLinie:match("(%S ) (%S ) (%S )")) , конечно.