Lua: соответствие шаблону после строки?

Например, у меня в таком формате есть произвольные строки:

каталог C: \ Program Files \ abc \ def \

или что-то в этом роде.

вход включен

Я хочу извлечь часть «C: \ Program Files \ ab \ def \» из этой первой строки. Точно так же я хочу извлечь «Вкл» во второй строке. Пробелы между переменной и ее значением произвольны. Я буду знать имя переменной, но мне нужно извлечь значение на основе этого.

По сути, я хочу удалить первое слово и несколько произвольных пробелов, следующих за первым словом, и вернуть то, что осталось до конца строки.


person tim tran    schedule 21.08.2012    source источник
comment
Кстати: у вас много вопросов, на которые есть довольно много ответов. Вы можете пройти их и принять некоторые из них, где это уместно.   -  person Nicol Bolas    schedule 21.08.2012


Ответы (3)


Предполагая, что под словом «слово» вы подразумеваете «строку символов без пробелов», вы можете сделать следующее:

for line in ioFile:lines() do
  local variable, value = line:match("(%S+)%s+(.+)")
  ... --Do stuff with variable and value
end
person Nicol Bolas    schedule 21.08.2012
comment
Привет. Я думаю, это должно сработать. Итак, если у меня есть переменная для строки. - person tim tran; 22.08.2012

Одну альтернативу с string.match показал Никол Болас, вот еще одна альтернатива:

function splitOnFirstSpace(input)
    local space = input:find(' ') or (#input + 1)
    return input:sub(1, space-1), input:sub(space+1)
end

Использование:

local command, param = splitOnFirstSpace(line)

Если аргумент не указан (splitOnFirstSpace('no-param-here')), то param - это пустая строка.

person Michal Kottman    schedule 22.08.2012
comment
будет ли это работать для произвольного количества пробелов между переменными и значением? - person tim tran; 22.08.2012
comment
Нет, не пойдет. Вам нужно будет вызвать input:find('%s+') и сохранить начальное и конечное местоположение пробела. Или вы можете потом обрезать параметры. - person Michal Kottman; 23.08.2012

Я не верю, что в Lua есть функция split (), такая как Ruby или Perl.

Я обнаружил, что этот парень создал lua-версию функции разделения Perl: http://lua-users.org/lists/lua-l/2011-02/msg01145.html

Если вы можете гарантировать, что перед аргументом будет только 1 слово, и это слово не будет содержать пробелов, вы можете прочитать в этой строке, запустить на ней функцию разделения и использовать значение индекса 1 возвращаемого массива, как вы хотите.

Вы также можете проверить это на ошибку и убедиться, что вы получили 'C: \' в ожидаемом каталоге, или убедитесь, что строка == установлена ​​на 'On' или 'Off'. Из-за использования жестко запрограммированного значения индекса я действительно рекомендую вам проверить ожидаемое значение на ошибку. Нет ничего хуже, чем ошибиться в предполагаемом значении.

Если обнаружена ошибка, обязательно зарегистрируйте или распечатайте ее на экране, чтобы вы знали об этом.

Это может выявить ошибки, когда введенная строка может быть неправильной.

Простой код, моделирующий то, что я предлагаю вам сделать:

line = "directory C:\Program Files\abc\def/";

contents = line.split(" "); --Split using a space
directory = contents[2]; --Here is your directory

if(errorCheckDir(directory))
--Use directory
end

РЕДАКТИРОВАТЬ: В ответ на комментарии ниже Lua действительно начинает индексирование с 1, а не с 0. Кроме того, в случае, если каталог содержит пробелы (что вероятно) вместо простого использования содержимого [2], я бы перебрал все содержимое, кроме индекса 1, и соберите каталог, убедившись, что между каждым присоединяемым индексом есть необходимое пространство.

Таким образом, в приведенном выше случае содержимое [2] и содержимое [3] нужно было бы снова сшить вместе с пробелом между ними, чтобы восстановить правильный каталог.

directory = contents [2] .. "" ..contents [3]

Это можно легко автоматизировать с помощью функции, которая имеет цикл и возвращает правильный каталог:

function recoverDir(contents)
    directory = "";
    --Recover the directory
    for i=2, table.getn(contents) do
        directory = directory..contents[i].." ";
    end
    --strip extra space on the end
    dirEnd = string.len(directory);
    directory = string.sub(directory,1,dirEnd-1);
    return directory; --proper directory
end
person Dean Knight    schedule 21.08.2012
comment
А что, если в каталоге есть пробелы, как в его примере? - person Nicol Bolas; 22.08.2012
comment
Не работает для пробелов; и таблицы lua индексируются с единицы. - person daurnimator; 22.08.2012
comment
Вы оба совершенно правы. @Nicol Я мог бы изменить приведенное выше, чтобы просто перебрать все, кроме первого результата разделения, и мы могли бы восстановить имя каталога, но это было бы беспорядочно, и я бы просто использовал ваше решение вместо этого Даурн: Полностью забыл о Lua, имеющем это поведение. Спасибо что подметил это. Я отредактирую приведенное выше, чтобы отразить эти изменения, чтобы полностью не запутать людей. - person Dean Knight; 22.08.2012