xparse 递归和/或特殊数字规范

xparse 递归和/或特殊数字规范

我需要解析“命令”,其中每个命令都是一串字母和数字:a34b56c32alpha

xparse没有什么办法来处理这些数字?

我想用类似的东西来指定它{ 'a' n 'b' n 'c' n m }

其中n为一个数字。

基本上,这是为了避免使用不必要的分隔符(它已经比较复杂,我无法使用,)。

我是新手xparse,在文档中没有看到任何有关能够解析数字的内容。

\documentclass[11pt]{book} % use larger type; default would be 10pt
%\documentclass[11pt,a4paper,oneside]{report}

\usepackage{pgffor}
\usepackage{xparse}
\begin{document}

\DeclareDocumentCommand{\Dotparse}{o m}
{
#1
}

% Passes each value in the array to an xparse command.
\def\Dots#1
{
    \foreach \n in {#1}{
        \Dotparse{\n}
}}

\Dots{[3]f4s3,f12s5,s2f14,[5]e,f,g,1,2,3,4,5,6,7}


\end{document}

此代码不解析可选命令

以上内容应该显示3, , , 5, , , , .... ,但我没有得到所有内容的值。不确定发生了什么。

无论如何,我想要的输出是

\Dots{[3]f4s3,f12s5,s2f14,[5]e,f,g,1,2,3,4,5,6,7}

解析为

[3](f + 4), s + 3, f + 12, s + 5, ...

这里的“+并不表示加法,而仅仅是一个分隔符。

所以#1 = 3, #2 = f, #3 = s, #4 = 4

(注意,不要被数组搞糊涂了,它是无关紧要的。我对它进行迭代,然后将元素传递给 xparser,这是我现在所关心的……例如,我想解析[3]f4s3它的标记,f4s3实际上有 4 个标记。f43s35对于我的目的来说仍然是 4)

例如,我可以编写一个这样的解析器x353.43y32.435z345.3cgreen 来用颜色表示 3d 点。显然,它看起来比使用命令或 = 符号更令人困惑,但它非常紧凑,这正是我想要的。

答案1

当尝试解析相对复杂的字符串时,LPeg 是最佳选择。它乍一看似乎有点复杂,但实际上并非如此。以下是我所学内容的一个非常简短的教程:

-- These are alias for lpeg's build in pattern matching functions
local P,C,V,Ct = lpeg.P, lpeg.C, lpeg.V, lpeg.Ct

-- This is lua dictionary that represents a grammar in lpeg notation
local p = {
    "S";  -- Start symbol
    S = V"Rule1" * V"Rule2",
    Rule1 =  P"a" * P"b",
    Rule2 = (P"c" + P"d")^0
}

lpeg.match(Ct(P(p)), parsestring)

重要的是模式匹配函数的类型、它们的组合方式(运算符)以及语法本身。

(请参阅 LPeg 文档了解完整描述)

  • P - 根据与该字符串完全匹配的字符串创建模式
  • V - 创建规则的逻辑引用。用于将一个规则用作另一个规则的模式
  • C - 创建捕获点。当解析器匹配到该点时,它会将结果粘贴到表中
  • Ct - 创建捕获表。捕获表包含所有子捕获(使用 C)。您可以通过这种方式创建嵌套表,然后解析它们。

  • '*' - 按顺序组合模式。示例中的规则 1 将仅匹配字符串“ab”

  • '+' - 允许“或”模式。规则 2 将匹配字符串“c”或“d”或不匹配(由于 ^0)。它是“有序的”,因为它会在从第一个模式到最后一个模式检查时立即返回匹配项。因此,如果我们有 P"a" + P"ab",我们将在字符串“ab”上得到“a”,因为 P"a" 匹配第一个“a”。
  • '-' - 阻止匹配。patt1 - patt2 将首先尝试匹配字符串中的 patt2。如果此失败然后它将尝试匹配 patt1,如果 patt1 存在则返回匹配。如果 patt2 匹配则整个模式失败。例如,“a”-“ba”在“ba”、“baa”、“badfe”上会失败,但在“a”、“aba”、“aaa”上会成功,因为“ba”在开始时不匹配。
  • '^' - 允许重复规则。^0 将尽可能地尝试匹配规则,但最多 0 次。

还有更多的 lpeg 函数和运算符以及“重复”控制(使用 ^ 运算符)。

基本思路是简单地设置 lpeg 语法表然后匹配它。要创建语法表,您需要使用 lpeg 的模式匹配结构来表示您的语法。为了能够用它做有用的事情,您需要使用捕获函数来捕获数据或将函数应用于匹配。

示例中的语法将匹配字符串 ab、abc、abd、abcadsfd、abd2f$F3 等。它之所以会匹配 ab/abc/abd 之后的任何内容,是因为我们没有为起始规则提供停止条件(可以用 -1 表示行尾)。

以下是一些有用的链接:

相关内容