String 正在寻找一个基于Lua的解决方案,用于将字符串拆分为两个或多个组件

String 正在寻找一个基于Lua的解决方案,用于将字符串拆分为两个或多个组件,string,lua,String,Lua,这是我第一次在这个网站上发帖,请耐心等待 考虑以下具有代表性的字符串: fld u.a. ldfjal \verb*u.a.* dlf \lstinline$u.a.$ u.a. dfla \url{u.a.}rrr 对于某些背景:\verb*…*和\lstline$…$是LaTeX宏,其参数不是通过匹配的大括号来分隔的,而是通过一个公共字符来分隔的:*对于\verb和\lstline。重要的一点是,分隔符字符可以是除{和}之外的任何可打印ASCII字符;我们不应该假设*或$将在所有(甚至任何

这是我第一次在这个网站上发帖,请耐心等待

考虑以下具有代表性的字符串:

fld u.a. ldfjal \verb*u.a.* dlf \lstinline$u.a.$ u.a. dfla \url{u.a.}rrr
对于某些背景:
\verb*…*
\lstline$…$
是LaTeX宏,其参数不是通过匹配的大括号来分隔的,而是通过一个公共字符来分隔的:
*
对于
\verb
\lstline
。重要的一点是,分隔符字符可以是除
{
}
之外的任何可打印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的字符串库函数的解决方案,但没有取得任何进展-(

熟悉Lua的字符串模式

“[^}{]”
将匹配任何字符,但例如
“}”
“{
除外

捕获:

“{([^{}]*)}”
这将捕获任意数量的字符,但
“{”
“}”
用大括号括起来

你所要做的就是把所有的事情拼凑在一起

试试这个:

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
您必须为感兴趣的每个原语执行一个循环,但至少分隔符部分会自行处理。

假设:

  • 宏名称仅由字母和
    @
  • 分隔符只能是数字或标点符号,除了
    @\
守则:

-- 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)

如果您给出示例输入字符串的预期输出,而不是给出一些NNNNYYYNNN,那么事情会变得更清楚thing@Piglet-谢谢。理想情况下,“输出”可以输入一个
string.gsub
函数,该函数的第三个组件是一个Lua函数,它不在“Y”上运行部分并对“N”部分进行进一步的字符串操作(通过另一个string.gsub调用)。如果这样做太困难,我会非常乐意使用一种顺序算法来分离“Y”和“N”部分(我对“N”部分进行进一步的处理)。同样,“N”部分将是LaTeX宏
\verb
lstlinline
\url
及其各自的参数。这是否澄清了问题?根据最初的问题,不能保证完整字符串包含“N”组件。此外,命令可以像
\verb |\lstinline+nested use+|
那样嵌套,在这种情况下,只需计算相关的最外层命令,直到相应的结束符号为“Y”部分,但仍然每个字符串可能包含任意数量的有问题的命令。这并不能真正帮助排序用任何字符分隔的字符串,如分隔符为
\verb+something+
,或分隔符为
+
\verb$something$
。这背后的挑战是。@TeXnician我不知道我不知道你的意思。你能再举一个例子吗?因为“\verb[^{}]([^{}]*)[^{}]”完美地给出了“\verb$something$”或“\verb+something+”或“\verbasomethinga”中的“某物”。我真傻,忘了它,你是对的。我看到的与OP任务的唯一冲突是
\url{something}
东西不能同时被捕获。@TeXnician-这个
\url{something}
部分实际上很简单:它由
\url%b{}
:-)匹配@小猪-我不是真的想从
\verb&something&
中提取
\verb&something&
。相反,我想从,比如说,
djfaldfja;l\verb&something&dlfja;slfdjal
中提取
不是预先知道的。相反,它必须根据上下文确定,作为
\verb
之后的第一个字符。我非常喜欢您的解决方案,但是:命令
\verb
不能用匹配的花括号括住它的参数,但可以这样使用:
\verb{test{
这是LaTeX的有效语法,但您的解决方案未检测到。同时,
\lstinline
可以与
\lstinline{test}
一起使用,但不能与
\lstinline{test{
\lstinline}test}
一起使用。您的解决方案仍然令人惊讶!有人真的编写了类似
\verb{test test test的东西吗{
?我不会,但如果您需要逐字表达式中的其他字符,这是可能的,而且可能是合理的。此外,
\verb
\lstinline
可能由匹配的数字分隔(如果不使用像
\csname
这样的特殊宏,宏名称中不允许使用这些数字)哇,你的代码正是我需要的!!非常感谢。请查看你的代码在现实排版问题中的应用。
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