Lua:在分隔符字符串中查找标记

3

我有一个包含一组分隔符标记的字符串,看起来像这样:

local str = "foo;bar;baz"

我希望能够准确判断给定的令牌是否在这个字符串中:

in_str("foo", str) -- true
in_str("bar", str) -- true
in_str("baz", str) -- true
in_str("ba", str) -- false
in_str("foo;", str) -- false

使用PHP和正则表达式,我会像这样完成所需的效果:
function in_str($needle, $haystack) {
    return (bool)preg_match('/(^|;)' . preg_quote($needle, '/') . '(;|$)/', $haystack);
}

我不确定如何将这个逻辑转换成Lua代码。我更希望使用原始的Lua语言实现,不需要任何插件、扩展等。同时,我希望它的效率要合理。目前为止,我唯一能正确实现的方法是将字符串分割成表格,然后遍历它。但这显然非常低效。


3
为什么显然低效呢?正则表达式通常速度较慢。 - Robert Harvey
由于线性搜索的时间复杂度为O(n),这还没有计算每次需要拆分字符串的时间。 - FtDRbwLXw6
除非您的字符串中有数千个标记(或者您正在处理数千个这样的字符串),否则这可能是过早的优化。如果您正在构建编译器,可能有更好的方法来完成此操作,例如将标记放入字典中。然后您将处于O(1)而不是O(n)。 - Robert Harvey
这个函数每秒钟会被调用数十次,因此我认为这不是过早的优化。 - FtDRbwLXw6
是的,这是一个实时系统。之前没有提到,抱歉。 - FtDRbwLXw6
显示剩余5条评论
2个回答

4
这是代码示例的工作样本:链接
local str = "foo;bar;baz;and;some;more;random;data;in;here"
function check(sString, sData)
  print( string.find(";"..sString..";", ";"..sData..";") )
end
check( str, "foo" )
check( str, "bar" )
check( str, "ba" )
check( str, "baz" )
check( str, "random" )
check( str, "stuff" )

我已经编辑了这个答案,以修复一些导致误报/漏报的情况。尽管如此,它似乎仍然是最有效的方法。谢谢。 - FtDRbwLXw6
@drrcknlsn 我也尝试过,不过我的方法有点不同,在这里 - hjpotter92
是的,那个方法肯定更具有容错性。 - FtDRbwLXw6

1

由于Lua的模式匹配API中没有逻辑或(|)运算符,因此您可以尝试使用以下方法:

function in_str(needle, haystack)
  return (haystack:find(';' .. needle .. ';') or
          haystack:find('^' .. needle .. ';') or
          haystack:find(';' .. needle .. '$')) ~= nil
end

local str = "foo;bar;baz"

print(in_str("foo", str))  -- true
print(in_str("bar", str))  -- true
print(in_str("baz", str))  -- true
print(in_str("ba", str))   -- false
print(in_str("foo;", str)) -- false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接