寻找一种基于 Lua 的解决方案来将字符串拆分成两个或更多组件
2017-8-14 19:15:46
收藏:0
阅读:103
评论:3
这是我在这个网站上的第一篇帖子,请多多包涵。
考虑以下相对典型的字符串:
fld u.a. ldfjal \verb*u.a.* dlf \lstinline$u.a.$ u.a. dfla \url{u.a.}rrr
一些背景:\verb*....*和\lstline$...$是 LaTeX 宏,其参数不是由匹配的花括号分隔的,而是由常见字符分隔的:在\verb的情况下为*,在\lstinline的情况下为$。一个重要的点是分隔符字符可以是任何可打印的 ASCII 字符,除了{和}; 不应该假设在所有(或即使是任何)情况下将使用*或$作为分隔符。另外,\url{...}是一个 LaTeX 宏,其参数由花括号分隔。应该假定完整字符串包含 utf8 编码字符; 为简单起见,让我们假设它们是纯 ASCII 字符。
我想创造一个(希望是相当高效的...)基于 Lua 的方法来将完整字符串拆分成两组子字符串:(a)由 LaTeX 宏及其关联参数组成的部分和(b)其他部分。最终目标是将“其他部分”提供给一个 string.gsub 函数调用。
转向前面的示例,如何将字符串分离
fld u.a. ldfjal \verb*u.a.* dlf \lstinline$u.a.$ u.a. dfla \url{u.a.}rrr
成为“Y”(在 verbatim 类似的宏内)和“N”(不在 verbatim 类似的宏内)组件,即,
NNNNNNNNNNNNNNNNYYYYYYYYYYYNNNNNYYYYYYYYYYYYYYYYNNNNNNNNNNNYYYYYYYYYYNNN
哦,每个字符串保证有“N”组件,但可能没有“Y”组件。该字符串可以原则上从“N”或“Y”组件开始和结束。
我一直在尝试提出一种使用 Lua 的字符串库函数的解决方案,但根本没有进展。 :-(
点赞
用户107090
尝试一下:
s=[[
fld u.a. ldfjal \verb*u.a.* dlf \lstinline$u.a.$ u.a. dfla \url{u.a.}rrr
]]
-- 使用 gmatch 进行匹配,获取每个 primitive 类型、分隔符和包含内容
for a,b,c in s:gmatch("(\\verb(.)(.-)%2)") do
print(a,b,c)
end
你需要为每个你感兴趣的原始码类型循环一次,但至少分隔符部分可以自动处理。
2017-08-14 21:25:35
用户6834680
假设:
- 宏名仅由字母和
@组成 - 分隔符只能是数字或标点符号字符,除了
@ \
代码:
- 指定每个宏的参数数量,
- 对于支持匹配大括号{}的宏,请使用负数
local all_macros = {
verb = 1,
url = -1,
lstinline = -1,
["@Some@Macros"] = -2,
makeatletter = 0
}
- 列出所有分隔符(仅标点符号和数字)
local all_delimiters = [[!"#$%&'*+,-./:;<=>?^_`|~()[]{}0123456789]]
- 指定用于处理字符串的N部分的函数
local function convert(N_substring)
return N_substring:upper()
end
- 现在进行处理
local s = [[
fld u.a. ldfjal \verb{u.a.{ dlf \lstinline{u.a.} u.a. dfla
\url{u.a.}rrr \@Some@Macros~u.a.~{u.a.}{u.a.}qq\verb|\lstinline+nested use+qqq|q
]]
s = s:gsub("\\([%a@]+)",
function(macro_name)
if all_macros[macro_name] then
return
"\1\\"..macro_name
..(all_macros[macro_name] < 0 and "\2" or "\3")
:rep(math.abs(all_macros[macro_name]) + 1)
end
end
)
repeat
local old_length = #s
repeat
local old_length = #s
s = s:gsub("\2(\2+)(%b{})", "%2%1")
until old_length == #s
s = s:gsub("[\2\3]([\2\3]+)((["..all_delimiters:gsub("%p", "%%%0").."])(.-)%3)", "%2%1")
until old_length == #s
s = ("\2"..s.."\1"):gsub("[\2\3]+([^\2\3]-)\1", convert):gsub("[\1\2\3]", "")
- 打印结果
print(s)
输出:
FLD U.A. LDFJAL \verb{u.a.{ DLF \lstinline{u.a.} U.A. DFLA
\url{u.a.}RRR \@Some@Macros~u.a.~{u.a.}{U.A.}QQ\verb|\lstinline+nested use+qqq|Q
2017-08-15 08:00:11
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的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 代码?

让自己熟悉 Lua 的字符串模式。
例如,
"[^}{]"将匹配除了"}"或"{"以外的所有字符。捕获:
"{([^{}]*)}"这将捕获花括号所包裹的任意数量的非"{"或"}"字符。你所要做的就是把所有这些拼在一起。
https://www.lua.org/pil/20.2.html