【问题标题】:Lua: Finding a token in a delimited stringLua:在分隔字符串中查找标记
【发布时间】:2012-07-16 04:02:57
【问题描述】:

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

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。我也希望能够在 vanilla Lua 中做到这一点,而不需要任何插件/扩展/等。我也希望它相当有效。到目前为止,我设法正确实现这一点的唯一方法是将字符串拆分为一个表,然后对其进行迭代,这显然是非常低效的。

【问题讨论】:

  • which is obviously very inefficient. -- 为什么明显效率低下?正则表达式通常较慢。
  • 因为线性搜索是O(n),这还不算每次都要拆分字符串。
  • 除非您的字符串中有数千个标记(或者您正在处理数千个这样的字符串),否则这可能是过早的优化。如果您正在构建编译器,则可能有更好的方法来执行此操作,例如将标记放入字典中。然后你会在 O(1),而不是 O(n)。
  • 这个函数每秒会被调用几十次,所以我不觉得这是过早的优化。
  • 是实时系统?

标签: string lua


【解决方案1】:

以下是工作代码示例:LINK

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" )

【讨论】:

  • 我已经编辑了这个答案以修复一些它给出误报/否定的情况。不过,这似乎是最有效的方法。谢谢。
  • @drrcknlsn 我自己也试过了,虽然我的方法有点不同,here
  • 是的,那个方法肯定更容错。
【解决方案2】:

由于 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    相关资源
    最近更新 更多