String 当我们不使用';你没有卢阿的`| `操作符吗?
我有以下形式的字符串:String 当我们不使用';你没有卢阿的`| `操作符吗?,string,lua,lua-patterns,String,Lua,Lua Patterns,我有以下形式的字符串: cake!apple! apple! cake!juice!apple!cake! juice!cake! 换句话说,这些字符串由三个子字符串组成“蛋糕!”,“苹果!”和“果汁!” 我需要验证这些字符串。因此,使用正则表达式执行此操作的方法是: /^(apple!|juice!|cake!)*$/ 但是Lua的模式没有|操作符,所以似乎不能这样做 如何在Lua中验证字符串 (我不关心字符串的内容:我只关心它们是否符合(验证) 我知道如何编写代码来实现这一点,但我
cake!apple!
apple!
cake!juice!apple!cake!
juice!cake!
换句话说,这些字符串由三个子字符串组成“蛋糕!”
,“苹果!”
和“果汁!”
我需要验证这些字符串。因此,使用正则表达式执行此操作的方法是:
/^(apple!|juice!|cake!)*$/
但是Lua的模式没有|
操作符,所以似乎不能这样做
如何在Lua中验证字符串
(我不关心字符串的内容:我只关心它们是否符合(验证)
我知道如何编写代码来实现这一点,但我想不出一个简单的方法来实现这一点。我正在寻找一个简短的解决方案。我不知道是否有一个优雅的解决方案,我不知道。有什么想法吗?我不知道这是否能帮你解决这个问题。但是使用string.find()我可以使用“或”。看:
致以最诚挚的问候Lua模式不能替代正则表达式,也不能表示这种模式。在这种情况下,您只需反复确保字符串的前面与您的一个单词匹配,然后将其弹出,但您可能已经知道了这一点。如果字符串中有一个永远不会出现的字符,例如,字符
“\1”
(ASCII1
)在正常字符串中不太可能出现,您可以使用以下方法:
local str = "cake!juice!apple!cake!"
if str:gsub("apple!","\1"):gsub("juice!","\1"):gsub("cake!","\1"):gsub("\1","") == "" then
--do something
end
通过将模式的每个匹配项替换为“\1”
,最后将“\1”
替换为空字符串,正确的匹配项最终将是空字符串
它有缺陷(有时不可能找到字符串中不存在的字符),但我认为它在许多情况下都能工作。以下内容似乎适用于(包括)快速测试
local strs = {
"cake!apple!",
"bad",
"apple!",
"apple!bad",
" apple!bad",
"cake!juice!apple!cake!",
"cake!juice! apple!cake!",
"cake!juice!badapple!cake!",
"juice!cake!",
"badjuice!cake!",
}
local legalwords = {
["cake!"] = true,
["apple!"] = true,
["juice!"] = true,
}
local function str_valid(str)
local newpos = 1
for pos, m in str:gmatch("()([^!]+!)") do
if not legalwords[m] then
return
end
newpos = pos + m:len()
end
if newpos ~= (str:len() + 1) then
return nil
end
return true
end
for _, str in ipairs(strs) do
if str_valid(str) then
print("Match: "..str)
else
print("Did not match: "..str)
end
end
比如:
local words = {cake=1,apple=2,juice=3}
local totals = {}
local matches = 0
local invalid = 0
string.gsub("cake!","(%a+)!",
function(word)
local index = words[word]
if index then
matches = matches + 1
totals[index] = totals[index] + 1
else
invalid = invalid + 1
end
end
)
if matches > 0 and invalid == 0 then
-- Do stuff
end
这将把每个字传递给提供的函数,您可以在其中验证每个字
if str:gsub("%w+!", {["apple!"]="", ["juice!"]="", ["cake!"]=""}) == "" then
--do something
end
此解决方案使用表作为第二个参数来创建。由于模式都匹配%w+
,因此表将再次验证,只有真正的三个模式被替换为空字符串。如果在所有替换之后,字符串变为空,则匹配成功
使用helper表变量可以使其更清楚:
local t = {["apple!"]="", ["juice!"]="", ["cake!"]=""}
if str:gsub("%w+!", t) == "" then
--do something
end
为了提供另一个答案,您可以使用lpeg的
re
模块轻松完成此任务:
re = require 're'
local testdata =
{
"cake!apple!",
"apple!",
"cake!juice!apple!cake!",
"cake!juice!badbeef!apple!cake!",
"juice!cake!",
"badfood",
}
for _, each in ipairs(testdata) do
print(re.match(each, "('cake!' / 'apple!' / 'juice!')*") == #each + 1)
end
这将产生:
true
true
true
false
true
false
这看起来几乎像上面的正则表达式模式减去
^
$
当然,因为lpeg匹配总是锚定的。这不符合您的想法。这不起作用:-),“蛋糕!”或“teste”
只给出“蛋糕!”
,尝试打印(“蛋糕!”或“teste”)
。所以你的建议相当于打印(string.find(str,“cake!”)。哼。。。有趣。谢谢你为什么不直接用一个空字符串来替换呢?也就是说,为什么不做str:gsub(“苹果!”,”)
?@NiccoloM。这也会让“juiapple!ce!”通过。谢谢;这是我一直在寻找的简短解决方案!
true
true
true
false
true
false