2016-01-22 1 views
3

Я пытаюсь упростить сценарий, и мои попытки не работают. Я делаю функцию, которая передаст данные аргументы и превратит их в индексированную таблицу, но я хочу иметь возможность передавать как кавычки, так и без кавычек, а функция распознает, что цитируемые аргументы считаются одним значением, а также -которые аргументы.Lua: Котируемые аргументы передаются как один в функции

Например:

makelist собака «коричневая мышь» кошка тигр «красочный попугай»

должен возвращать индексированную таблицу, как следующее:

list_table = {"dog", "brown mouse", "cat", "tiger", "colorful parrot"} 

код, который я имею дела для цитаты, но это беспорядок на не кавычки, и, кроме того, добавляет цитируемые аргументы во второй раз. Вот что у меня есть:

function makelist(str) 
    require 'tprint' 
    local list_table = {} 
    for word in string.gmatch(str, '%b""') do 
    table.insert(list_table, word) 
    end 
    for word in string.gmatch(str, '[^%p](%a+)[^%p]') do 
    table.insert(list_table, word) 
    end 
    tprint(list_table) 
end 

Я не понимая, почему упущение кавычки игнорируется, а также отрубить первую букву. То есть, это выход я получаю от tprint (функция, которая печатает таблицу из, не относящиеся к коду):

makelist('dog "brown mouse" cat tiger "colorful parrot"') 
1=""brown mouse"" 
2=""colorful parrot"" 
3="og" 
4="rown" 
5="mouse" 
6="cat" 
7="tiger" 
8="olorful" 
9="parrot" 

Как вы можете видеть, «D», «B» и «с ' не хватает. Какие исправления мне нужно сделать, чтобы я мог получить следующий результат?

1="brown mouse" 
2="colorful parrot" 
3="dog" 
4="cat" 
5="tiger" 

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

ответ

2
local function makelist(str) 
    local t = {} 
    for quoted, non_quoted in ('""'..str):gmatch'(%b"")([^"]*)' do 
    table.insert(t, quoted ~= '""' and quoted:sub(2,-2) or nil) 
    for word in non_quoted:gmatch'%S+' do 
     table.insert(t, word) 
    end 
    end 
    return t 
end 
+0

что, не комментарий на этот раз ?!;) Это не будет работать на несбалансированные кавычки, например, примерить 'Foo«unbalanced', хотя можно утверждать, что это добродетель. –

+0

Ха-ха, очень добродетель, я полагаю! Удивительный ответ на это! И ничего себе, я удивлен, ты на самом деле ответил вместо комментариев! Спасибо, Егор! – Josh

2

Может быть проще просто разбить на пробелы и объединить те элементы, которые находятся внутри кавычек. Нечто подобное может работать (я добавил несколько больше случаев испытания):

function makelist(str) 
    local params, quoted = {}, false 
    for sep, word in str:gmatch("(%s*)(%S+)") do 
    local word, oquote = word:gsub('^"', "") -- check opening quote 
    local word, cquote = word:gsub('"$', "") -- check closing quote 
    -- flip open/close quotes when inside quoted string 
    if quoted then -- if already quoted, then concatenate 
     params[#params] = params[#params]..sep..word 
    else -- otherwise, add a new element to the list 
     params[#params+1] = word 
    end 
    if quoted and word == "" then oquote, cquote = 0, oquote end 
    quoted = (quoted or (oquote > 0)) and not (cquote > 0) 
    end 
    return params 
end 
local list = makelist([[ 
dog "brown mouse" cat tiger " colorful parrot " "quoted" 
in"quoted "terminated by space " " space started" next "unbalanced 
]]) 
for k, v in ipairs(list) do print(k, v) end 

Это печатает следующий список для меня:

1 dog 
2 brown mouse 
3 cat 
4 tiger 
5 colorful parrot 
6 quoted 
7 in"quoted 
8 terminated by space 
9 space started 
10 next 
11 unbalanced 
+0

Это не работает при сбалансированных котировках: '' terminated by space 'next' –

+0

Отличная работа над этим! Егор немного более простой, но человек, мне очень жаль, что я не мог дать приемлемые ответы всем. Вместо этого я надеюсь, что все будут отвечать на все эти замечательные ответы! Благодаря! – Josh

+1

Должен быть исправлен для строк, запущенных/завершенных пробелами. –

1

Первого спасибо за ваш вопрос, заставил меня изучить основы Lua !

Во-вторых, поэтому я думаю, что вы пошли с вашим решением в некотором неправильном направлении. Глядя на вопрос, который я только что сказал, почему вы не расщепляется один раз в кавычки (") и чем выбрать, где вы хотите разделить на пространстве

Это то, что я придумал:.

function makelist(str) 
    local list_table = {} 
    i=0 
    in_quotes = 1 
    if str:sub(0,1) == '"' then 
    in_quotes = 0 
    end 
    for section in string.gmatch(str, '[^"]+') do 
    i = i + 1 
    if (i % 2) == in_quotes then 
     for word in string.gmatch(section, '[^ ]+') do  
     table.insert(list_table, word) 
     end 
    else 
     table.insert(list_table, section) 
    end 
    end 
    for key,value in pairs(list_table) do print(key,value) end 
end 

результат:

1 dog 
2 brown mouse 
3 cat 
4 tiger 
5 colorful parrot 
+0

Я рад, что смог помочь вам чему-то научиться! Ха-ха! Иногда, насколько я знаю о Луа, я, как правило, усложняю ситуацию. Я даю вам один, потому что ваш ответ полностью скатился, но принятый ответ проделал то же самое, что и вы. Но основные реквизиты! – Josh

Смежные вопросы