首页 > 其他 > 详细

Lpeg

时间:2019-06-13 11:52:21      阅读:146      评论:0      收藏:0      [点我收藏+]

LPeg是一个为Lua所使用的新的模式匹配库,基于解析表达式语法(PEGs)。

  • 用基本匹配函数,组合匹配表达式
  • 所有匹配函数返回userdata类型,是一个匹配模式(以下用pattern代替),可相互组合.

Simple Matching 简单匹配

local lpeg = require "lpeg"

local match = lpeg.match    -- 对字符串匹配给定的模式
local P = lpeg.P    -- 从字面上匹配一个字符串
local S = lpeg.S    -- 匹配集合中的任何东西
local R = lpeg.R    -- 匹配在一定范围内的任何东西

-- 匹配字符串的开头,成功则返回匹配之后的位置,失败返回nil
print(match(Paaaa))   -->2
print(match(Pa123))   -->nil

-- 匹配一个范围之内,匹配一个集合之内
print(match(R09123))  -->2
print(match(S123123)) -->2

-- 匹配一个以上的项
print(match(Pa^1aaa)) -->4

-- 符号*组合模式,匹配a之后,再匹配0或多个b
print(match(Pa*Pb^0abbc))   -->4

-- 组合模式,匹配一个或0个a,再匹配b
local maybe_a = Pa^-1
local match_ab = maybe_a * b
print(match(match_ab, ab))    -->3
print(match(match_ab, b))     -->2
print(match(match_ab, aaab))  -->nil

-- 符号+匹配其中任意一个
local either_ab = (Pa + Pb)^1
print(either_ab:matchaaa)     -->4
print(either_ab:matchbbaa)    -->5

Basic Captures 基本捕获

local lpeg = require "lpeg"

local match = lpeg.match    -- 对字符串匹配给定的模式
local P = lpeg.P    -- 从字面上匹配一个字符串
local S = lpeg.S    -- 匹配集合中的任何东西
local R = lpeg.R    -- 匹配在一定范围内的任何东西

local C = lpeg.C    -- 捕获匹配
local Ct = lpeg.Ct  -- 一个从模式捕获过来的表

-- 捕获数字
local digit = R09     -- 任何0到9的数
local digits = digit^1  -- 至少要有一个数字
local cdigits = C(digits)
print(cdigits:match123)   -->123

-- 包含+-符号
local int = S+-^-1 * digits
print(match(C(int), +23)) -->+23

-- 对捕获的字符串通过一个功能
print(match(int/tonumber+123) + 1)  -->124

-- 返回多个捕获,就像string.match
print(match(C(Pa^1) * C(Pb^1), aabbbb))   -->aa   bbbb

Building more complicated Patterns 构建更复杂的模式

local lpeg = require "lpeg"

local match = lpeg.match    -- 对字符串匹配给定的模式
local P = lpeg.P    -- 从字面上匹配一个字符串
local S = lpeg.S    -- 匹配集合中的任何东西
local R = lpeg.R    -- 匹配在一定范围内的任何东西

local C = lpeg.C    -- 捕获匹配
local Ct = lpeg.Ct  -- 一个从模式捕获过来的表

-- 考虑一般的浮点数,等同于正则[-+]?[0-9]+\.?[0-9]+([eE][+-]?[0-9]+)?
function maybe(p) return p^-1  end
local digits = R09^1
local mpm = maybe(S+-)
local dot = .
local exp = SeE
local float = mpm * digits * maybe(dot * digits) * maybe(exp *mpm * digits)
print(match(C(float), 2.3))   -->2.3
print(match(C(float), -2))    -->-2
print(match(C(float), 2e-02)) -->2e-02

-- 从列表识别数字
local listf = C(float) * (, * C(float))^0
print(listf:match2,3,4)   -->2    3   4

-- 放进实际的表
print(match(Ct(listf), 1,2,3))    -->table: 003FAEE0
local tList = match(Ct(listf), 1,2,3)
for i = 1, #tList do
    print(tList[i])
end
-->1
-->2
-->3

-- 转换类型
local floatc = float/tonumber
listf = floatc * (, * floatc)^0

-- 忽略空格
local sp = P ^0
function space(pat) return sp * pat * sp end
local floatc = space(float/tonumber)
local listc = floatc * (, * floatc)^0
print(match(listc, 1,2, 3))   -->1    2   3

-- 匹配标识符
function list(pat)
    pat = space(pat)
    return pat * (, * pat)^0
end
local idenchar = R(AZaz) + P_
local iden = idenchar * (idenchar + R09)^0
print(list(C(iden)):matchhello, dolly, _x, s23)   -->hello    dolly   _x  s23

-- 使用语言环境无关定义
local l = {}
lpeg.locale(l)
for k in pairs(l) do print(k) end
--[[
punct
alpha
alnum
digit
graph
xdigit
upper
space
print
cntrl
lower
--]]
iden = (l.alpha + P_) * (l.alnum + P_)^0
print(list(C(iden)):matchhello, dolly, _x, s23)   -->hello    dolly   _x  s23

-- 类似的CSV格式
local rlistf = list(float/tonumber)
local csv = Ct((Ct(rlistf) + \n)^1)
local tcsv = csv:match1,2.3,3\n10,20, 30\n
for i = 1, #tcsv do
    for j = 1, #tcsv[i] do
        print(tcsv[i][j])
    end
end
--[[
1
2.3
3
10
20
30
--]]

 

Lpeg

原文:https://www.cnblogs.com/slysky/p/11015171.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!