这个Lua中的去制表符(detab)函数是如何工作的?
-- 将制表符转换为空格 function detab(text) local tab_width = 4 local function rep(match) local spaces = -match:len() print("match:"..match) while spaces<1 do spaces = spaces + tab_width end print("Found "..spaces.." spaces") return match .. string.rep(" ", spaces) end text = text:gsub("([^\n]-)\t", rep) return text end
str=' thisisa string' -- thiis is a string
print("length: "..str:len()) print(detab(str)) print(str:gsub("\t"," "))
```
我有一段来自 markdown.lua 的代码将制表符转换为空格(正如其名称所示)。
我设法弄清楚了它是如何从字符串的开头查找制表符并将匹配的子字符串传递给 'rep' 函数的。它会这样重复,直到找不到匹配项。
我在尝试弄清楚 'rep' 函数在做什么特别是在 while 循环中出现的问题。
为什么循环停在 1?
为什么它要计算增量?
令人惊讶的是,它计算字符串中的空格数量,如何进行的仍然是个谜。
如果您将其输出与最后一个 gsub 替换的输出进行比较,您会发现它们是不同的。 Detab 保持了字符的对齐,而 gsub 替换没有。 这是为什么?
额外的问题。当我在 Scite 中打开空格时,我可以看到 't' 前的制表符比第三个 's' 前的制表符长。 它们为什么不同?
从分析 rep 函数来看,它似乎是在做这件事情。首先,它获取传入的匹配字符串的长度,并将其变为负数(例如相当于乘以-1)。在 while 循环中,它不断将 space 加到它变成正数为止。
可以使用数字线更容易地可视化这一点:
<--|----|-------|----|----|----|----|----|----|----|----|--->
-n -spaces -2 -1 0 1 2 n
实质上,该循环试图确定有多少个 "tab_widths" 可以适合在 space 中 "溢出"。在这里,它使用了从 0 到 1 的过渡作为分界点。循环结束后,spaces 将显示其溢出量。
实际上,while 循环模仿了您可能知道的一个数学运算,即取模。换句话说,内部 rep 函数可以重写为:
local function rep(match)
local spaces = tab_width - match:len() % tab_width
return match .. string.rep(" ", spaces)
end
这与外层 str:gsub("\t", " ") 不同,它 不加选择地 用 4 个空格替换所有制表符字符。另一方面,在 detab 函数中,替换制表符字符的空格数量取决于匹配捕获的长度。
例如:
匹配长度为 1,则使用 3 个空格替换制表符
匹配长度为 2,则使用 2 个空格替换制表符
匹配长度为 3,则使用 1 个空格替换制表符
匹配长度为 n,则使用 tab_width - (n % tab_width) 个空格替换制表符
依此类推。
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
回答奖励问题:
制表符会对齐到制表位。制表位是八个字符。第一个制表符从第六列开始,所以需要填充三个空格。第二个制表符从第16列开始,所以只需要一个空格宽度。
循环会在空格变成正数时停止,因为循环已经以“缩进”增量添加空格,直到拥有足够的空格长于匹配文本。当将该数量的空格与匹配文本结合起来时,构造了一个填充到正确制表位的字符串。
这也是为什么gusub不同的原因。gsub不是将制表符视为制表位字符,而是将制表符视为四个空格。因此,第二个制表符不会填充到制表位,而是扩展为四个空格。
```markdown