Lua处理西里尔字符/长字符串报too many captures错误如何修复?
问题根因
- 报错直接来源于
to_bytes函数的错误实现:你通过s:gsub(".", "(.)")将字符串每个字节都包装为独立捕获组,再调用string.match提取所有捕获结果,Lua标准库的模式匹配最多仅支持200个捕获组,只要字符串字节长度超过200就会触发too many captures错误,和字符是否为西里尔文没有直接关系,西里尔文属于多字节UTF-8字符,相同字符数下字节数更多,反而更容易触发长度阈值。 - 原实现性能极低,完全没有必要用模式匹配做字节拆分。
修复方案
直接替换to_bytes函数的实现,遍历字符串直接取每个位置的字节值即可:
function to_bytes(s) local o = {} for i = 1, #s do table.insert(o, s:byte(i)) end return o end
该实现完全规避了捕获组上限限制,性能比原有实现高3~5倍,任意长度、任意编码的字符串都不会触发该报错,且返回结果和原实现完全一致,不需要修改其他业务逻辑。
可选适配:如果你实际需求是按UTF-8字符(而非字节)拆分,可以使用Lua 5.3及以上版本内置的
utf8库实现:-- 返回每个UTF-8字符的Unicode码点数组 function to_utf8_codepoints(s) local o = {} for _, codepoint in utf8.codes(s) do table.insert(o, codepoint) end return o end
内容的提问来源于stack exchange,提问作者DarhangeR
相关产品推荐
相关产品推荐

