Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 当我们不使用';你没有卢阿的`| `操作符吗?_String_Lua_Lua Patterns - Fatal编程技术网

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”
(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”
替换为空字符串,正确的匹配项最终将是空字符串


它有缺陷(有时不可能找到字符串中不存在的字符),但我认为它在许多情况下都能工作。

以下内容似乎适用于(包括)快速测试

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