如何在lua中通过regexp重复匹配多个表达式

时间:2014-01-19 11:06:50

标签: regex lua

我正在学习lua。在regexp中有一些问题。 我有一些字符串:

text = "aaab1aaac-aac1d2b5hhpt456d5h9h8"

我希望得到结果:

"b1", "c1b2b5", "t4", "d5h9h8"

我将代码编写如下。

local st,ed
while true do
    st,ed = string.find(text,"([a-z][1-9])+",ed)  --the regexp
    if st==nil then
        break
    else
        print(string.sub(text,st,ed))
    end
    ed=ed+1
end

但它没有打印出正确的结果

4 个答案:

答案 0 :(得分:2)

试试这个trick of the trade

text = "aaab1aaac-aac1d2b5hhpt456d5h9h8"
aux = text:gsub("%l%d","\1\1")

for b,e in aux:gmatch("()\1+()") do
    print(text:sub(b,e-1))
end

答案 1 :(得分:1)

以下是使用LPEG的替代方法,在这种情况下使用直接循环:

function findzigs(text)
    local items = {}
    local zigzag = nil
    local prevI1=-2
    local i1,i2 = text:find("%a%d") 
    while i1~=nil do
        local pair = text:sub(i1,i2)
        if i1-2 == prevI1 then
             zigzag = zigzag .. pair
        else
             if zigzag then table.insert(items, zigzag) end
             zigzag = pair
        end
        prevI1 = i1
        i1,i2 = text:find("%a%d", i2+1) 
    end
    if zigzag then table.insert(items, zigzag) end
    return items
end

可能会被清除以删除重复的“if zigzag”和“text:find”,但你明白了。它可以提供您所需的结果。

答案 2 :(得分:0)

我不知道lua,但这个正则表达式怎么样:

"((?:[a-z][1-9])+)"

答案 3 :(得分:0)

正如@Yu Hao已经提到的那样 comment, Lua模式不同于和不太强大 “正则表达式”我们大多数人都习惯了。 但这实际上不是一个问题,因为Lua提供了优秀的服务 LPEG library,是 由该语言的主要开发人员编写。

您要求的模式可以用LPEG编写如下:

local lpeg      = require "lpeg"
local lpegmatch = lpeg.match
local R, C      = lpeg.R, lpeg.C

local match_alpha_n_digit
do
  local alpha       = R "az" -- + R "AZ" -- for uppercase
  local digit       = R "09"
  local sequence    = C ((alpha * digit)^1) -- capture longest sequence of (alpha, digit) pairs
  local pattern     = (sequence + 1)^1
  match_alpha_n_digit = function (str)
    if not str or type (str) ~= "string" then return end
    return lpegmatch (pattern, str)
  end
end

text   = "aaab1aaac-aac1d2b5hhpt456d5h9h8"

print (match_alpha_n_digit (text))
--- or capture the result in a table:
some_table = { match_alpha_n_digit (text) }

这样它包含在函数match_alpha_n_digit()中 你可以在表构造函数中调用。

也可以编写一个接收任意额外的模式 然后我们可以使用参数在匹配时检索这些参数 捕获 (lpeg.Carg())。 此方法允许使用函数迭代所有匹配:

local lpeg      = require "lpeg"
local lpegmatch = lpeg.match
local R, C      = lpeg.R, lpeg.C
local Cmt, Carg = lpeg.Cmt, lpeg.Carg

local iter_alpha_n_digit
do
  local alpha       = R "az"
  local digit       = R "09"
  local sequence    = Cmt (C((alpha * digit)^1) * Carg (1),
                           function (_, _, match, fun)
                             fun (match)
                             return true
                           end)
  local pattern     = (sequence + 1)^1

  iter_alpha_n_digit = function (str, fun)
    if not str or type (str) ~= "string"   then return end
    if not fun or type (fun) ~= "function" then return end
    return lpegmatch (pattern, str, nil, fun)
  end
end

text   = "aaab1aaac-aac1d2b5hhpt456d5h9h8"

iter_alpha_n_digit (text, print) -- iterate matches with the print() function

这里我们将内置print()函数应用于匹配项,但是 它可能是任何其他功能。