我需要解析“命令”,其中每个命令都是一串字母和数字: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 表示行尾)。
以下是一些有用的链接: