2009-07-17 4 views
2

Я пытаюсь использовать string.find в Lua для анализа содержимого введенной пользователем строки. Есть три различных параметра, которые я пытаюсь найти (если пользователь вводит их), но иногда только один.Образец соответствия с строковым модулем Lua

входной строки в более длинной форме выглядит следующим образом:

 
local userInput = "x|y|z" 

где x, y и z может быть любой символ или ничего (пустая строка, то есть "") и z также может содержать вертикальные полосы/трубы - я хочу разделить строку на три секции на основе первых двух вертикальных баров ("|"). Трудность состоит в том, что пользователь также не может использовать эту форму - он может просто ввести "x" или "x||z" или "||z" и т. Д. В этом случае мне все равно нужно будет получать значения x, y и z, и это должно быть ясно, какие переменные им назначены.

Например, я попытался это:

 
local _,_,a,b,c = string.find(usermsg, "([^|]*)|?([^|]*)|?(.+)") 

Отметим прежде всего, что это даже и не правильно получать a, b и c правильно. Но что более важно, когда usermsg был только "x", он устанавливает значение x переменной c, когда это должно быть a. И когда пользователь вводит "x|y", переменная a равна x (правильно), но переменная c равна y (неверно, она должна быть назначена переменной b).

Итак, я попытался сделать это отдельно:

 
local _,_,a = string.find(usermsg , "([^|]+)|?[^|]*|?.*") 
local _,_,b= string.find(usermsg , "[^|]*|([^|]+)|?.*") 
local _,_,c= string.find(usermsg , "[^|]*|[^|]*|(.+)") 

Но это также не удается. Он соответствует x, но не y, а c заканчивается y плюс труба и z.

Любая помощь будет оценена по достоинству. Благодаря! :)

ответ

0

Это должно работать, как вы намерены

local _,_,a,b = string.find(usermsg, "([^|]*)|?(.*)") 
local _,_,b,c = string.find(b, "([^|]*)|?(.*)") 
+0

если пользовательский ввод является "| б | с", которая возвращает а = "а" Ь = "а" с = "| B | C" – 2009-07-17 02:45:44

+0

Какую версию LUA вы используете? Я тестирую его на v5.1.4 и возвращает ожидаемые значения. – 2009-07-17 03:01:42

+0

Я использую версию 5.1 – 2009-07-17 05:11:20

1

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

function string.split(str, delim, max, special) 
    if max == nil then max = -1 end 
    if delim == nil then delim = " " end 
    if special == nil then special = False end 
    local last, start, stop = 1 
    local result = {} 
    while max ~= 0 do 
     start, stop = str:find(delim, last, not special) 
     if start == nil then 
      -- if max > #(all ocurances of delim in str), we end here  
      break 
     end 
     table.insert(result, str:sub(last, start-1)) 
     last = stop+1 
     max = max - 1 
    end 
    -- add the rest 
    table.insert(result, str:sub(last)) 
    return result 
end 

print(("A='%s' B='%s' C='%s'"):format(unpack(("hello|there|world"):split('|', 2)))) 
print(("A='%s' B='%s' C='%s'"):format(unpack(("||world"):split('|', 2)))) 
print(("A='%s' B='%s' C='%s'"):format(unpack(("hello||world"):split('|', 2)))) 
print(("A='%s' B='%s' C='%s'"):format(unpack(("hello|there|"):split('|', 2)))) 
print(("A='%s' B='%s' C='%s'"):format(unpack(("hello||world|and|the|rest"):split('|', 2)))) 

=>

A='hello' B='there' C='world' 
A='' B='' C='world' 
A='hello' B='' C='world' 
A='hello' B='there' C='' 
A='hello' B='' C='world|and|the|rest' 
0

Я думаю, что лучшим решением этой проблемы является string.match

local a, b, c = string.match("(^|*)|(^|*)|(.*)") 

^| соответствует ничего, что не | и * означает, что он будет соответствует 0 или более.