String 卢阿布尔人唐';在redis中没有预期的行为
我有剧本String 卢阿布尔人唐';在redis中没有预期的行为,string,lua,redis,match,string-matching,String,Lua,Redis,Match,String Matching,我有剧本 local fields = redis.call('hkeys', 'a:hash:full:of:stuff'); local retval = {}; for i, field in pairs(fields) do if((string.match(tostring(field),'ev')) ~= nil) then retval[i] = {field, (string.match(tostring(field),'ev') ~= nil) }
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
for i, field in pairs(fields) do
if((string.match(tostring(field),'ev')) ~= nil) then
retval[i] = {field, (string.match(tostring(field),'ev') ~= nil) }
end
end
return retval
此脚本返回一个空列表
当我将if
语句更改为
if((string.match(tostring(field),'.')) ~= nil) then
...
我得到了一个很长的列表,其中包括以下内容
...
...
60) 1) "applet:1:metric:viewelement:20130607"
2) (nil)
61) 1) "applet:1:total_events:20130529"
2) (integer) 1
...
...
如果我将if语句替换为
if(1)
我得到了同样长的钥匙清单
我还尝试过使用string.find
,它也有类似的行为
唯一似乎是一个模式的事情是,如果匹配的字符串在字符串中出现多次,或者出现在开头,则if
语句将通过。我不能肯定,但这可能会有帮助
我使用以下命令运行此脚本
$ redis-cli eval "$(cat get_keys.lua)" 0
。您只需执行if(string.match(tostring(field),'ev'))
some\u table[1]
、some\u table[2]
和some\u table[5]
,然后返回数组,它看起来会以some\u table[2]
结束。由于只在if语句通过时设置数组,因此如果它在retval[1]
上失败,数组的其余部分将不会返回李>
简单的解决方法是:
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
for i, field in pairs(fields) do
if(string.match(tostring(field),'ev')) then
retval[i] = {field, (string.match(tostring(field),'ev') ~= nil) }
else retval[i] = 'some_nil_value'
end
end
return retval
我想你也可以用,但我还没有玩过,所以不能在这里提供太多信息
[编辑]OP声明他不想要零占位符。在这种情况下,可以使用以下各项:
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
for i, field in pairs(fields) do
if(string.match(tostring(field),'ev')) then
retval[#retval+1] = {field, (string.match(tostring(field),'ev') ~= nil) }
end
end
return retval
Eli的答案是可行的,但我认为这是因为Lua处理列表的方式存在微妙的问题。我想解释一下我的想法 因此,作为测试,我在
retval
中插入了一个额外的字段,有时它是零。我注意到,在这些电话中,列表的其余部分没有返回
我认为在幕后发生的是redis正在处理整个列表,但是当它返回时,它在第一次nil
时被截断。所以有时候有一个列表,有时候没有。作为一名黑客,我将剧本改写为
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
local i = 0
for j, field in pairs(fields) do
if string.find(field,"ev") then
retval[i] = {field, string.match(field,'ev') }
i = i+1;
end
end
return retval
成功了
所以Eli的答案是有效的,因为
retval
没有被截断。但是,当您需要解析返回的列表时,它会占用更多的带宽和cpu时间。在调试过程中,脚本中有一些额外的内容。这是可行的,但不是optimal@PeterKlipfel在哪些方面不是最优的?您也许可以通过使用默认表来提高一点点性能,但我怀疑这会对基准测试产生任何影响。我的意思是我在回答中所说的。我应该指定它对于我的用例不是最佳的,这将包括解析出放入数组中的nil值。我确信我的解决方案可以被预绑定,但它使用的内存较少。您最初的解决方案有一个与hkeys
调用大小相同的数组,返回时带有零占位符。如果您想避免使用nil占位符,那么首先为什么要问这个问题?不管怎样,如果你想要的话,我会用一种更简洁的方式修改我的答案,以避免占位符。对不起,我不是有意让自己听起来像个朋克。我给出了我的答案,因为在任何人遇到这个答案的情况下,gotcha可能有助于调试。它的好处是返回一个较小的列表。我不知道为什么我没有把我的名单拿回来