2009-07-17 6 views
2

Ich versuche string.find in Lua zu verwenden, um den Inhalt einer vom Benutzer eingegebenen Zeichenfolge zu analysieren. Es gibt bis zu drei verschiedene Parameter, die ich versuche zu finden (wenn der Benutzer sie eingibt), aber manchmal nur eine.Pattern Matching mit Lua's String-Modul

Die Eingabezeichenfolge in seiner längeren Form wie folgt aussieht:

 
local userInput = "x|y|z" 

wo x, y und z kann jedes Zeichen oder nichts (leere Zeichenkette, dh "") und z auch vertikale Balken enthalten/Pfeifen - Ich möchte die Saite nur in drei Abschnitte aufteilen, basierend auf den ersten beiden vertikalen Balken ("|"). Die Schwierigkeit besteht darin, dass der Benutzer kann nicht auch diese Form verwenden - er oder sie kann einfach "x" oder "x||z" oder "||z" usw. In diesem Fall eintreten würde ich noch die Werte von x, y erhalten muß, und z, und es sollte sein klar, welchen Variablen sie zugeordnet wurden.

Zum Beispiel habe ich versucht, dies:

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

Hinweis zunächst, dass dies nicht richtig selbst a holen, b und c richtig. Aber was noch wichtiger ist, wenn der usermsg nur "x" war, setzte er den Wert x auf die Variable c, wenn es a sein sollte. Und wenn der Benutzer "x|y" eintippt, ist die Variable ax (korrekt), aber die Variable c ist y (falsch, sollte der Variablen b zugewiesen werden).

So dann habe ich versucht, es separat zu tun:

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

Aber dies nicht gelingt auch. Es passt x, aber nicht y, und c endet als y plus das Rohr und z.

Jede Hilfe wäre willkommen. Vielen Dank! :)

Antwort

0

Dies sollte funktionieren, wie Sie

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

wenn Benutzereingaben "a | b | c", die a = "a" b = "a" c = gibt "| b | c" –

+0

Welche Version von LUA verwenden Sie? Ich teste es auf Version 5.1.4 und es gibt die beabsichtigten Werte zurück. –

+0

Ich benutze Version 5.1 –

1

scheint die Absicht, dass Sie mit einer max Anzahl der Teilungen suchen Sie nach Ihrer typischen Split-Funktion nur. Hier ist mein:

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

Ich denke, die beste Lösung für dieses Problem ist string.match

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

^| alles passt, die nicht | ist, und * bedeutet, es wird Treffe 0 oder mehr.