根据正则解析出实例数据

前端之家收集整理的这篇文章主要介绍了根据正则解析出实例数据前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
<!-- lang: lua -->
local f = require('DataGenerator')

function test_data (data) local i = 0 for _,patt in ipairs(data) do --print(patt) for _,k in ipairs(f(patt)) do --print(k) if string.match(k,patt) then i = i + 1 print('ok ' .. i .. ' - "' .. k .. '" match /' .. patt .. '/') end end end end

local data = { '^bde^de$xx$' }

test_data(data)

<!-- lang: lua -->
-- 单数组最大记录

local array_limit = 100 -- + * 最大上限 10 { n,} 增加的限度 local max_rep_times = 10 -- 数组连接,超出最大记录数后,每次递增的记录数 local step_length = 1

local unpack = table.unpack or unpack

local function error (...) print(...) os.exit() end

-- 将 {num} {num,}{num,num} 格式的字符串 -- 解析成 数据格式,也就是一个数组 local function parse_quantifier_str (str) local array = {} local mode = 0 local num_str = '' for char in string.gmatch(str,'.') do -- 初始化模式 if mode == 0 then -- 遇到开始符号,才能进入另外的模式 if char == '{' then mode = 1 end -- 开始解析 elseif mode == 1 then -- 遇到字符,添加到缓冲,状态升级 if string.match(char,'%d') then num_str = char mode = 2 elseif not char == ' ' then error('error:01:class difine with no digit numer') end elseif mode == 2 then -- 接着遇到数字就添加进去 if string.match(char,'%d') then num_str = num_str .. char -- 如果遇到逗号,模式改变 elseif char == ',' then table.insert(array,tonumber(num_str)) num_str = '' mode = 3 elseif char == '}' then -- {5} => {5,5} table.insert(array,tonumber(num_str)) table.insert(array,tonumber(num_str)) num_str = '' break -- 如果遇到除空格之外的字符,就是一个错误 elseif not char == ' ' then error('error:02:quantifier with non digit char') end elseif mode == 3 then -- 遇到结束符号,就退出了 -- 因为上个字符是逗号,所以就是 { num,} 模式 if char == '}' then table.insert(array,array[1] + max_rep_times) break -- 如果是数字 elseif string.match(char,'%d') then mode = 4 num_str = char elseif not char == ' ' then error('error:03: wrong char in class str') end -- 上次的符号是,逗号, elseif mode == 4 then -- 继续遇到数字的话,就继续添加 if string.match(char,'%d') then num_str = num_str .. char elseif char == '}' then table.insert(array,tonumber(num_str)) break elseif not char == ' ' then error('error:04: wrong char in class str') end end end return array end

local function concat_array (a1,a2) local limit = limit or array_limit local max_length = 1 if #a1 > max_length then max_length = #a1 end if #a2 > max_length then max_length = #a2 end if max_length > limit then limit = max_length + step_length end

count = 0 local a = {} for _,v1 in ipairs(a1) do for _,v2 in ipairs(a2) do table.insert(a,v1 .. v2) count = count + 1 end if count > limit then break end end return a end

-- 将多个数组合并 local function concat_multi_array (array) if #array == 1 then return array[1] elseif #array == 2 then return concat_array(unpack(array)) elseif #array > 2 then local a1 = table.remove(array) local a2 = table.remove(array) local a = concat_array(a2,a1) table.insert(array,a) return concat_multi_array(array) end end

local function concat_rep_array (array,rep_times) local rep_array = {} if rep_times == 0 then return { '' } end if rep_times == 1 then return array end for i = 1,rep_times do table.insert(rep_array,array) end return concat_multi_array(rep_array) end

-- class and quantifier to array local function cnq_to_array (a) local combin_array = {} for _,value in ipairs(a) do local class,quant = unpack(value) local array = {} local from,to = unpack(quant) for i = from,to do local i_array = concat_rep_array(class,i) -- 将生成的记录加入原有的记录中 for _,v in ipairs(i_array) do table.insert(array,v) end end table.insert(combin_array,array) end return combin_array end

local count = 128 local char_id = {}

-- 申请一个ID,从 128开始-。如果是有参数为 1 -- 那么就同时生成一个 table 作为 char_id local function apply_id_char (id,mode) mode = mode or 0 count = count + 1 local char = string.char(count) char_id[char] = id if mode == 1 then char_id[char] = { id = id } end return char end

-- 获取字符的原始字符 local function get_char_id (char) local value = char_id[char] if type(value) == 'table' then return value.id elseif type(value) == 'string' then return value else error('error:05:not exists id records: ' .. char) return nil end end

-- 获取字符的代表字符集 local function get_char_class (char)

-- if not get_char_id(char) then print(char) end local array = {} -- 使用可见字符 for i = 0,126 do local i_char = string.char(i) local patt = '' if char == '.' then patt = char else patt = '%' .. get_char_id(char) end if string.find(i_char,patt) then table.insert(array,i_char) end end return array end

-- 根据 class char of quantifier char get matched str with pos local function get_char_str (char,pos) local str_list = char_id[char] -- 不要使用数字作为 table 的索引,因为这是数组的地盘 if str_list then return str_list[pos] else error('error:06:not exists char record') end end

-- 获取数量字符表,并同时能获得对应的数量数据结构 local quantifier_char_table = { ['+'] = { 1,max_rep_times },['*'] = { 0,['-'] = { 0,['?'] = { 0,1},} -- 获取其他的转义字符的字符列表。用于替换 local escape_id_table = {}

-- class_char_table,char is class local class_str = 'a c d l p s u w x z A C D L P S U W X Z' local class_char_table = { ['.'] = '.' } for id in string.gmatch(class_str,'%S') do local id_char = apply_id_char(id) class_char_table[id_char] = id escape_id_table[id] = id_char end

-- 有些字符的转义需要隐藏,以便对不转义的字符进行的处理 local conceal_str = '+ - * ? [ ] ( ) { } % .' local conceal_char_table = {} for id in string.gmatch(conceal_str,'%S') do local id_char = apply_id_char(id) conceal_char_table[id_char] = id escape_id_table[id] = id_char end

-- [...] => class_char -- 将 user 自定义字符集结构进行字符化 local user_class_char = apply_id_char('[...]',1)

-- {num,num} {num} {num,} => quantifier_char -- 将自定义数量结构进行字符化 local user_quantifier_char = apply_id_char('{...}',1)

-- [0-8 a-z] -- 区间字符定义 local user_range_char = apply_id_char('[n-m]',1)

function process_patt_str (patt)

-- first ^ and end $ is not any uses patt = string.gsub(patt,'^%^','') patt = string.gsub(patt,'%$$','')

-- replace all escape magic char to other char -- 对所有转义的字符进行处理,应用规则 -- 用相应的字符代替 patt = string.gsub(patt,'%%(.)',function (id) if escape_id_table[id] then return escape_id_table[id] end return id end)

-- could not add user defined class to class char patt = string.gsub(patt,'%[.-%]',function (str) table.insert(char_id[user_class_char],str) return user_class_char end)

-- also could not add user defined quantifier to quantifier char patt = string.gsub(patt,'{%d+,?%d-}',function (str) table.insert(char_id[user_quantifier_char],str) return user_quantifier_char end) return patt end

-- 将 [...] 格式的字符串解析成 数组,字符数组 local function parse_class_str (str) -- 预处理字符集字符串 -- 将 .-. 结构的捕获出来 -- 叫做 char_range -- 获取其中 a-z 0-9 A-Z 的结构 local range_char_table = {} str = string.gsub(str,'(.)%-(.)',function (from,to) local class = {} local from_index = string.byte(from) local to_index = string.byte(to) for i = from_index,to_index do table.insert(class,string.char(i)) end table.insert(range_char_table,class) return user_range_char end)

-- 其中的字符有 class 字符,除此以外,都是字符 -- 只有两种模式 local mode = 0 local reverse_mode = 0 local range_pos = 1 -- 用散列保存字符集,以去重 local char_table = {} for char in string.gmatch(str,'.') do if mode == 0 then if char == '[' then mode = 1 end elseif mode == 1 then mode = 2 if char == '^' then reverse_mode = 1 elseif class_char_table[char] then local class = get_char_class(char) for _,k in ipairs(class) do char_table[k] = 1 end elseif char == user_range_char then -- print('call here') local class = range_char_table[range_pos] range_pos = range_pos + 1 for _,k in ipairs(class) do char_table[k] = 1 end elseif conceal_char_table[char] then local id = get_char_id(char) char_table[id] = 1 elseif char == ']' then error('error:07:without class define') break else char_table[char] = 1 end elseif mode == 2 then if class_char_table[char] then local class = get_char_class(char) for _,k in ipairs(class) do char_table[k] = 1 end elseif conceal_char_table[char] then local id = get_char_id(char) char_table[id] = 1 elseif char == ']' then break else char_table[char] = 1 end end end -- 将去重后的字符集合并成数组输出,可以进行排序 local array = {} -- 如果 class 前面定义有 ^ 标志 if reverse_mode == 1 then for i = 0,126 do local char = string.char(i) if not char_table[char] then table.insert(array,char) end end else for k,_ in pairs(char_table) do table.insert(array,k) end -- 如果没有的话,顺序就是乱的,需要排序 table.sort(array,function (a,b) return a < b end) end return array end

-- patt to array 解析 pattern to array -- { {char_list,amount},{char_list. amount} } local function patt_to_array (patt) local array = {} -- return array local class = {} local mode = 0 -- 定位在 class_char 的位置指针 local class_pos = 1 -- 定位在 quantifier_char 的位置指针 local quantifier_pos = 1 -- 如果末尾是 - 那么就连最后一个 class 一起删除 patt = string.gsub(patt,'-$','?') -- 在末尾添加一个字符以结束解析 patt = patt .. '$' for char in string.gmatch(patt,'.') do -- 初始化模式 mode = 0 if mode == 0 then -- 字符集字符,动态获取 if class_char_table[char] then class = get_char_class(char) mode = 1 -- 数量字符,进行映射 elseif quantifier_char_table[char] then error('error:08:quantifier char could not at begin') -- 转义字符,要进行恢复 -- 自定义字符集 elseif char == user_class_char then local str = get_char_str(char,class_pos) class = parse_class_str(str) class_pos = class_pos + 1 mode = 1 -- 自定义数量字符 elseif char == user_quantifier_char then error('error:09:user quantifier could not at begin') elseif conceal_char_table[char] then local id = get_char_id(char) class = { id } mode = 1 else -- 其他字符处理 class = { char } mode = 1 end

-- 如果是字符,或字符集模式 1
elseif mode == 1 then
  -- 初始化 quantifier
  local quantifier = {1,1}

  -- if it is quantifer identifer,then mode = 0
  -- and get defined quantifer
  if quantifier_char_table[char] then
    quantifier = quantifier_char_table[char]
    mode = 0
  elseif char == user_quantifier_char then
    local str = get_char_str(char,quantifier_pos)
    quantifier = parse_quantifier_str(str)
    quantifier_pos = quantifier_pos + 1
    mode = 0
  end
  -- push current class and quantifier to array
  table.insert(array,{ class,quantifier })

  -- if meet new class char,then create new class
  if class_char_table[char] then
    class = get_char_class(char)
  elseif char == user_class_char then
    local str = get_char_str(char,class_pos)
    class = parse_class_str(str)
    class_pos = class_pos + 1
  elseif conceal_char_table[char] then
    local id = get_char_id(char)
    class = { id }
  else
    class = { char }
  end
end

end return array end

function DataGenerator (str,mode) mode = mode or 0 local patt = process_patt_str(str) local array = patt_to_array(patt) local data = cnq_to_array(array) return concat_multi_array(data) end

return DataGenerator

原文链接:https://www.f2er.com/regex/362916.html

猜你在找的正则表达式相关文章