我有以下形式的字符串:
cake!apple!
apple!
cake!juice!apple!cake!
juice!cake!
换句话说,这些字符串由三个子字符串"cake!"
,"apple!"
和"juice!"
组成。
我需要验证这些字符串。因此,使用正则表达式执行此操作的方法是:
/^(apple!|juice!|cake!)*$/
但是Lua的模式没有|
运算符,因此它似乎无法以这种方式完成。
如何在Lua中验证我的字符串?
(我不关心字符串的内容:我只关心它们是否符合(验证)。)
我知道要编写代码来执行此操作,但我想不出一个简短的方法来执行此操作。我正在寻找一个简短的解决方案。我想知道是否有一个我不知道的优雅解决方案。有什么想法吗?
答案 0 :(得分:5)
if str:gsub("%w+!", {["apple!"]="", ["juice!"]="", ["cake!"]=""}) == "" then
--do something
end
此解决方案使用表作为string.gsub
的第二个参数。由于模式都匹配%w+
,表格将第二次验证,只有真正的三个模式被替换为空字符串。如果在完成替换后,字符串变为空,则匹配成功。
使用辅助表变量可以使其更清晰:
local t = {["apple!"]="", ["juice!"]="", ["cake!"]=""}
if str:gsub("%w+!", t) == "" then
--do something
end
答案 1 :(得分:2)
例如,如果字符中永远不会出现字符,则普通字符串中的字符"\1"
(ASCII 1
)不太可能,您可以使用:
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"
替换为空字符串,正确的匹配最后将是一个空字符串。
它有缺陷(有时候找不到字符串中的字符是不可能的),但我认为它适用于很多情况。
答案 2 :(得分: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
答案 3 :(得分:1)
只是提供另一个答案,您可以使用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匹配总是被锚定。
答案 4 :(得分:0)
Lua模式不是正则表达式的替代,也不能代表这种模式。在这种情况下,你只需要反复确保字符串的前面与你的一个单词匹配,然后将其弹出,但你可能已经知道了。
答案 5 :(得分:0)
类似的东西:
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
这会将每个单词传递给提供的函数,您可以在其中验证每个单词。
答案 6 :(得分:-3)
我不知道它是否会帮助你解决问题。但是使用string.find()我可以使用“或”。看:
str="juice!"
print(string.find(str, "cake!" or "teste"))
最好的问候