Lpeg

LPeg是一個爲Lua所使用的新的模式匹配庫,基於解析表達式語法(PEGs)。git

  • 用基本匹配函數,組合匹配表達式
  • 全部匹配函數返回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(P'a''aaa'))   -->2
print(match(P'a''123'))   -->nil

-- 匹配一個範圍以內,匹配一個集合以內
print(match(R'09''123'))  -->2
print(match(S'123''123')) -->2

-- 匹配一個以上的項
print(match(P'a'^1'aaa')) -->4

-- 符號*組合模式,匹配a以後,再匹配0或多個b
print(match(P'a'*P'b'^0'abbc'))   -->4

-- 組合模式,匹配一個或0個a,再匹配b
local maybe_a = P'a'^-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 = (P'a' + P'b')^1
print(either_ab:match'aaa')     -->4
print(either_ab:match'bbaa')    -->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 = R'09'     -- 任何0到9的數
local digits = digit^1  -- 至少要有一個數字
local cdigits = C(digits)
print(cdigits:match'123')   -->123

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

-- 對捕獲的字符串經過一個功能
print(match(int/tonumber'+123') + 1)  -->124

-- 返回多個捕獲,就像string.match
print(match(C(P'a'^1) * C(P'b'^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 = R'09'^1
local mpm = maybe(S'+-')
local dot = '.'
local exp = S'eE'
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:match'2,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('AZ''az') + P'_'
local iden = idenchar * (idenchar + R'09')^0
print(list(C(iden)):match'hello, 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)):match'hello, dolly, _x, s23')   -->hello    dolly   _x  s23

-- 相似的CSV格式
local rlistf = list(float/tonumber)
local csv = Ct((Ct(rlistf) + '\n')^1)
local tcsv = csv:match'1,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
--]]

 http://lua-users.org/wiki/LpegTutorial%20ide

相關文章
相關標籤/搜索