[英]Splitting string into array string.components(separtedBy: “,”) consumes more time
[英]looking for a Lua-based solution for splitting a string into two or more components
这是我第一次发布到这个网站,所以请耐心等待。
考虑以下,有点代表性的字符串:
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”(在类似逐字宏的内部)和“N”(不在类似逐字宏的内部)组件,即
NNNNNNNNNNNNNNNNYYYYYYYYYYYNNNNNYYYYYYYYYYYYYYYYNNNNNNNNNNNYYYYYYYYYYNNN
哦,每个完整的字符串都保证有“N”个组件,但可能没有“Y”组件。 原则上,字符串可以以“N”或“Y”分量开始和结束。
我一直试图想出一个使用Lua的字符串库函数的解决方案,但还没有达到目的。 :-(
我们假设:
@
@\\
编码:
-- specify number of parameters for every macro,
-- use negative numbers for macros supporting matching pair of curly braces {}
local all_macros = {
verb = 1,
url = -1,
lstinline = -1,
["@Some@Macros"] = -2,
makeatletter = 0
}
-- list all the delimiters (only punctuation and digits)
local all_delimiters = [[!"#$%&'*+,-./:;<=>?^_`|~()[]{}0123456789]]
-- specify a function for processing N-part of the string
local function convert(N_substring)
return N_substring:upper()
end
-- Now do the processing
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 the result
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
尝试这个:
s=[[
fld u.a. ldfjal \verb*u.a.* dlf \lstinline$u.a.$ u.a. dfla \url{u.a.}rrr
]]
for a,b,c in s:gmatch("(\\verb(.)(.-)%2)") do
print(a,b,c)
end
你必须为你感兴趣的每个原语做一个循环,但至少分隔符部分会自行处理。
让自己熟悉Lua的字符串模式。
"[^}{]"
将匹配任何字符,但例如"}"
或"{"
。
捕获:
"{([^{}]*)}"
这将捕获任意数量的字符,但"{"
或"}"
由大括号括起来......
你所要做的就是把所有东西拼凑起来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.