如何在 Lua 中精确匹配模式的 n 次重复?

我正在编写一个只包含三个字母字符的语法。这是我的代码:

local l = require "lpeg"

l.locale(l)

local date = l.digit^1 * l.P'/' * l.digit^1 * l.P'/' * l.digit^1
local time = l.digit^1 * l.P':' * l.digit^1 * l.P':' * l.digit^1 * l.P':' * l.digit^1
local timezone = l.alpha^3
local stamp = l.P'[' * date * l.P' ' * time * l.P' ' * timezone * l.P']'

grammar = l.C(stamp)

我要匹配的输入是:

[4/23/15 4:49:49:371 CDT]

如何使表达式仅匹配时区中的三个字母字符?现在这段代码的工作方式是它将匹配三个或三个以上的字母字符。


奇怪!这可行吗?

local timezone = l.alpha*2

好像可以,但我找不到在这里引用该语法:

http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html

点赞
用户258523
用户258523

l.alpha*2 表示 l.alpha 重复匹配 2 次。

所以不,它匹配 [a-z]..

可以使用 lpeg.print(timezone) 命令查看结果。(注意我使用 ll 作为区域设置数据。将它放在同一个表中会丢失原始的 print 调试函数。)

> l=require"lpeg"
> ll=lpeg.locale()
> p=ll.alpha*2
> l.print(p)
[]
00: set [(41-5a)(61-7a)]-> FAIL
05: any * 2-> FAIL
06: end
> =p.match("099")
nil
> =p.match("EST")
4
> =p.match("E99")
4

你想要的模式是:

> function patcount(pat, min, max)
>>  return -pat^(max + 1) * pat^min
>> end
> p=patcount(ll.alpha, 3, 3)
> lpeg.print(p)
[]
00: set [(41-5a)(61-7a)]-> 27
05: choice -> 27 (1)
06: set [(41-5a)(61-7a)]-> FAIL
11: set [(41-5a)(61-7a)]-> FAIL
16: set [(41-5a)(61-7a)]-> FAIL
21: span [(41-5a)(61-7a)]
26: failtwice
27: set [(41-5a)(61-7a)]-> FAIL
32: set [(41-5a)(61-7a)]-> FAIL
37: set [(41-5a)(61-7a)]-> FAIL
42: span [(41-5a)(61-7a)]
47: end
> =p:match("EST")
4
> return p:match("ES")
nil
> return p:match("ESTT")
nil
> return p:match("099")
nil
> return p:match("E99")
nil

相关文档部分是 -patt

至于 l.alpha*2 语法,它由以下手册中的引用解释。

所有需要模式作为参数的操作也可以接收字符串、表格、数字、布尔值或函数,这些将根据函数 lpeg.P 的规则转换为模式。

这就是说,当操作数之一为模式时,运算符会将非模式转换为模式。

还有一个‘匹配一个固定次数的模式’部分(和链接)在 LpegRecipes lua-users.org 维基页面上。(但我没有完全了解这个实现,看起来比我上面的更复杂。)

2015-04-23 21:21:43