如何在 Lua 中精确匹配 n 次重复的模式?
How to match exactly n repetitions of a pattern in Lua?
我正在编写一个仅包含三个字母字符的语法。这是我的代码:
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
似乎是,但我在这里找不到引用的语法:
l.alpha*2
是 l.alpha
*
l.P(2)
.
所以不,匹配 [a-z]..
。
查看 lpeg.print(timezone)
的输出以确认这一点。 (请注意,我使用 ll
作为语言环境数据。将其放在相同的 table 中将失去原来的 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
语法,该语法由手册中的引述解释。
All operations that expect a pattern as an argument may receive also strings, tables, numbers, booleans, or functions, which are translated to patterns according to the rules of function lpeg.P.
也就是说,当操作数之一已经是模式时,运算符将非模式转换为模式。
在 LpegRecipes lua-users.org wiki 页面上还有 'Match a fixed number of repetitions of a pattern' 部分(和 link)。 (但我根本没有看过那个实现,它看起来比我上面的更复杂。)
我正在编写一个仅包含三个字母字符的语法。这是我的代码:
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
似乎是,但我在这里找不到引用的语法:
l.alpha*2
是 l.alpha
*
l.P(2)
.
所以不,匹配 [a-z]..
。
查看 lpeg.print(timezone)
的输出以确认这一点。 (请注意,我使用 ll
作为语言环境数据。将其放在相同的 table 中将失去原来的 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
语法,该语法由手册中的引述解释。
All operations that expect a pattern as an argument may receive also strings, tables, numbers, booleans, or functions, which are translated to patterns according to the rules of function lpeg.P.
也就是说,当操作数之一已经是模式时,运算符将非模式转换为模式。
在 LpegRecipes lua-users.org wiki 页面上还有 'Match a fixed number of repetitions of a pattern' 部分(和 link)。 (但我根本没有看过那个实现,它看起来比我上面的更复杂。)