Сопоставление с шаблоном с помощью строкового модуля Lua - PullRequest
2 голосов
/ 17 июля 2009

Я пытаюсь использовать string.find в 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.

Буду признателен за любую помощь. Спасибо! :)

Ответы [ 3 ]

1 голос
/ 25 июля 2009

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

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 голосов
/ 02 сентября 2016

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

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

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

0 голосов
/ 17 июля 2009

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

local _,_,a,b = string.find(usermsg, "([^|]*)|?(.*)")
local _,_,b,c = string.find(b, "([^|]*)|?(.*)")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...