2009-07-17 9 views
2

J'essaie d'utiliser string.find dans Lua pour analyser le contenu d'une chaîne entrée par l'utilisateur. Il y a jusqu'à trois paramètres différents que j'essaie de trouver (si l'utilisateur les entre), mais parfois seulement un.Motif Correspondance avec le module de chaîne de Lua

La chaîne d'entrée sous sa forme plus ressemble à:

 
local userInput = "x|y|z" 

x, y et z peut être un caractère ou rien (chaîne vide, c.-à-"") et z peuvent également contenir des barres verticales/pipes - Je veux seulement diviser la chaîne en trois sections basées sur les deux premières barres verticales ("|") rencontrées. La difficulté est que l'utilisateur peut également ne pas utiliser ce formulaire - il peut entrer simplement "x" ou "x||z" ou "||z", etc. Dans ce cas, je devrais encore obtenir les valeurs de x, y, et z, et il devrait être claires quant aux variables auxquelles elles ont été affectées.

Par exemple, j'ai essayé ceci:

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

Notez tout d'abord que cela ne même pas correctement a chercher, b et c correctement. Mais plus important encore, lorsque le usermsg était juste "x", il a mis la valeur de x à la variable c, alors qu'elle devrait être a. Et lorsque l'utilisateur tape "x|y", la variable a est (correcte) mais la variable c est y (incorrect, elle doit être affectée à la variable b).

Alors j'ai essayé de le faire séparément:

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

Mais cela échoue aussi. Il correspond x, mais pas y, et c finit par être y plus le tuyau et.

Toute aide serait appréciée. Merci! :)

Répondre

0

Cela devrait fonctionner comme vous avez l'intention

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

si l'entrée d'utilisateur est "a | b | c" qui retourne a = "a" b = "a" c = "| b | c" –

+0

Quelle version de LUA vous utilisez? Je le teste sur la version 5.1.4 et il renvoie les valeurs prévues. –

+0

J'utilise la version 5.1 –

1

Il semble que vous regardez juste pour votre fonction split typique avec un nombre maximum de divisions. Voici le mien:

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

Je pense que la meilleure solution à ce problème est string.match

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

^| correspond à tout ce qui est pas |, et * signifie qu'il correspond à 0 ou plus.

Questions connexes