lua工具库penlight(转)
2015-11-05 09:43
459 查看
简单的输入的模式
Lua 的字符串模式匹配是非常强大,通常您将不需要传统的正则表达式库。即便如此,有时 Lua 代码结束看上去像 Perl,因为字符串模式不容易阅读,尤其是对普通读者而言。这段代码需要了解三种不同的日期格式:
这些不是特别困难的模式,但典型问题已经出现,例如,不得不转义’ —’。此外, string.match返回其捕获,这样,我们被迫使用略显尴尬的嵌套的 if 语句。
验证码检验问题,使用正则表达式的人试图强制约束 (如一年不能超过四位数) 。我们应该享受匹配,而不是拿着锤子砸自己。
pl.sip提供了简单、 直观的方式来检测字符串中的模式和提取的相关部分。
sip = require ‘pl.sip’
dump = require(‘pl.pretty’).dump
res = {}
c = sip.compile ‘ref=Sfile:d{line}’
= c(‘ref=hello.c:10’,res)
true
dump(res)
{
line = 10,
file = “hello.c”
}
= c(‘ref=long name, no line’,res)
false
sip.compile可以从给定字符串和表创建一个模式匹配器函数。如果匹配字符串,则返回true ,根据模式中命名字段填充该表。
这里是另一个版本的日期分析器:
SIP 模式以’$’开始 ,之后跟着单字母类型,后面大括号中的是可选变量。
Type Meaning
v variable, or identifier.
i possibly signed integer
f floating-point number
r ‘rest of line’
q quoted string (either ’ or “)
p a path name
( anything inside (…)
[ anything inside […]
{ anything inside {…}
< anything inside <…>
[———————————]
S non-space
d digits
…
如果类型不是 v、 i、 f、 r 或 q 之一,它被假定为标准 Lua 字符。
你在模式中的任何空格将匹配任意数目的空格。
‘神奇’ 字符串中的任何字符均被转义。
SIP 捕获 (像vmon)不需要进行命名。您可以使用只是v,但你必须保持一致 ;如果一种模式包含未命名的捕获,然后所有捕获必须都是未命名。在这种情况下,结果表是一个简单的值列表。
sip.match是有用的快捷方式,如果你喜欢你 ‘占位’ 。(它将缓存结果,所以它比显式用sip.compile快些.)
sip.match(‘(qfirst,q{second})’,’(“john”,”smith”)’,res)
true
res
{second=’smith’,first=’john’}
res = {}
sip.match(‘(q,q)’,’(“jan”,”smit”)’,res) – unnamed captures
true
res
{‘jan’,’smit’}
sip.match(‘(q,q)’,’(“jan”, “smit”)’,res)
false —> oops! Can’t handle extra space!
sip.match(‘( q,q )’,’(“jan”, “smit”)’,res)
true
作为一般规则,允许您模式中的空白。
最后,放在模式的结尾的 ‘$’ 意味着 ‘捕获的在第一个非空格开头的行。
sip.match(‘( q,q ) $’,’(“jan”, “smit”) and a string’,res)
true
res
{‘jan’,’smit’,’and a string’}
res = {}
sip.match(‘( qfirst,q{last} ) $’,’(“jan”, “smit”) and a string’,res)
true
res
{first=’jan’,rest=’and a string’,last=’smit’}
命令行程序与 Lapp
pl.lapp是小而专注的Lua 模块,它的目的是要使标准命令行解析更方便和直观。它实现了 GNU 风格,即以短横线’-‘或长横线’ –’开始的字母。一般带参数的选项期望找到下一个输入作为它的参数 (例如 ’ gcc test.c -o test’),单个短选项可以忽略空格 (例如 ‘head -n4 test.c’ 或gcc -I/usr/include/lua/5.1 …)
Lapp 尽其可能将参数转换为等效的 Lua 类型,即转换数字、文件名转换为文件对象。如果任何转换失败,或缺少所需的参数,则将发出错误消息、 并用文本输出。所以有两个必要的任务,提供的标志和选项的名字,并将它们和类型关联。
对于任何非平凡的脚本,或仅为了个人消遣,有必要提供使用说明。Lapp 的新颖性是定义了松散格式的字符串用法,而且可以指定参数的名称和类型。
示例:
这里是在命令行的会话中使用此脚本:
luascale.luascale.lua:missingrequiredparameter:scaleDoessomecalculations−o,–offset(default0.0)Offsettoaddtoscalednumber−s,–scale(number)Scalingfactor(number)Numbertobescaled lua scale.lua -s 2.2 10
22
$ lua scale.lua -s 2.2 x10
scale.lua:unable to convert to number: x10
….(usage as before)
有两种类型的 Lapp 用法让字符串更有意义。短选项,可以选择其相应的长选项。可遵循括号中的类型说明符。同样,以 ‘<’ PARMETER ’ >’ 开头的参数行,后面跟着的是类型说明符。类型说明符是任一形式’(默认是 ‘VALUE’)’ 或 ‘(’ TYPE’)’ ;默认的说明符意味着选项或参数有默认值,并不是必需的。类型是一个 ‘字符串’、 ‘数’、 ‘文件输入’ 或 ‘文件输出’ ;VALUE是一个数字,(’stdin’、 ‘stdout’、 ‘stderr’) 之一或者是标记。这行的其余不会被分析,可以用作注释。
此脚本在输出表中显示的字段与指定的参数名称之间的关系。
上面显示了args表的所有参数 ;请注意,args.quiet 已经成为为 true,因为它被指定 ;args.p 默认为 false。如果有一个长命名选项,它将在选项中用作局部名称。因为默认的类型是布尔类型,对于简单的标志,它的类型或默认值不是必须的。
$ simple -o test -q simple.lua
p false
input file (781C1BD8)
quiet true
o test
input_name simple.lua
D:\dev\lua\lapp>simple -o test simple.lua one two three
1 one
2 two
3 three
p false
quiet false
input file (781C1BD8)
o test
input_name simple.lua
参数输入已设置为打开的只读文件对象 — — 我们知道它必须是一个只读的文件,因为它是默认值的类型。input_name字段会自动生成 ,因为它经常用来访问原始文件名。
请注意,提供的任意额外参数会放到整数索引表里,即 args [i] ,i表示1 到 #args 之间的值。
对有良好定义和明确任务的短脚本,文件真的不必显式关闭,因为垃圾收集文件对象的结果就是关闭它们。
参考资料:
lua工具库penlight:
http://www.csdn123.com/html/mycsdn20140110/78/78169e2b32e10c2286c9f89aa8ebc2e0.html
Penlight Lua Libraries 1.3.2:
http://stevedonovan.github.io/Penlight/api/index.html
Lua 的字符串模式匹配是非常强大,通常您将不需要传统的正则表达式库。即便如此,有时 Lua 代码结束看上去像 Perl,因为字符串模式不容易阅读,尤其是对普通读者而言。这段代码需要了解三种不同的日期格式:
-- parsing dates using Lua string patterns months={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6, Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12} function check_and_process(d,m,y) d = tonumber(d) m = tonumber(m) y = tonumber(y) .... end
for line in f:lines() do -- ordinary (English) date format local d,m,y = line:match('(%d+)/(%d+)/(%d+)') if d then check_and_process(d,m,y) else -- ISO date?? y,m,d = line:match('(%d+)%-(%d+)%-(%d+)') if y then check_and_process(d,m,y) else -- <day> <month-name> <year>? d,mm,y = line:match('%(d+)%s+(%a+)%s+(%d+)') m = months[mm] check_and_process(d,m,y) end end end
这些不是特别困难的模式,但典型问题已经出现,例如,不得不转义’ —’。此外, string.match返回其捕获,这样,我们被迫使用略显尴尬的嵌套的 if 语句。
验证码检验问题,使用正则表达式的人试图强制约束 (如一年不能超过四位数) 。我们应该享受匹配,而不是拿着锤子砸自己。
pl.sip提供了简单、 直观的方式来检测字符串中的模式和提取的相关部分。
sip = require ‘pl.sip’
dump = require(‘pl.pretty’).dump
res = {}
c = sip.compile ‘ref=Sfile:d{line}’
= c(‘ref=hello.c:10’,res)
true
dump(res)
{
line = 10,
file = “hello.c”
}
= c(‘ref=long name, no line’,res)
false
sip.compile可以从给定字符串和表创建一个模式匹配器函数。如果匹配字符串,则返回true ,根据模式中命名字段填充该表。
这里是另一个版本的日期分析器:
-- using SIP patterns function check(t) check_and_process(t.day,t.month,t.year) end shortdate = sip.compile('$d{day}/$d{month}/$d{year}') longdate = sip.compile('$d{day} $v{mon} $d{year}') isodate = sip.compile('$d{year}-$d{month}-$d{day}')
for line in f:lines() do local res = {} if shortdate(str,res) then check(res) elseif isodate(str,res) then check(res) elseif longdate(str,res) then res.month = months[res.mon] check(res) end end
SIP 模式以’$’开始 ,之后跟着单字母类型,后面大括号中的是可选变量。
Type Meaning
v variable, or identifier.
i possibly signed integer
f floating-point number
r ‘rest of line’
q quoted string (either ’ or “)
p a path name
( anything inside (…)
[ anything inside […]
{ anything inside {…}
< anything inside <…>
[———————————]
S non-space
d digits
…
如果类型不是 v、 i、 f、 r 或 q 之一,它被假定为标准 Lua 字符。
你在模式中的任何空格将匹配任意数目的空格。
‘神奇’ 字符串中的任何字符均被转义。
SIP 捕获 (像vmon)不需要进行命名。您可以使用只是v,但你必须保持一致 ;如果一种模式包含未命名的捕获,然后所有捕获必须都是未命名。在这种情况下,结果表是一个简单的值列表。
sip.match是有用的快捷方式,如果你喜欢你 ‘占位’ 。(它将缓存结果,所以它比显式用sip.compile快些.)
sip.match(‘(qfirst,q{second})’,’(“john”,”smith”)’,res)
true
res
{second=’smith’,first=’john’}
res = {}
sip.match(‘(q,q)’,’(“jan”,”smit”)’,res) – unnamed captures
true
res
{‘jan’,’smit’}
sip.match(‘(q,q)’,’(“jan”, “smit”)’,res)
false —> oops! Can’t handle extra space!
sip.match(‘( q,q )’,’(“jan”, “smit”)’,res)
true
作为一般规则,允许您模式中的空白。
最后,放在模式的结尾的 ‘$’ 意味着 ‘捕获的在第一个非空格开头的行。
sip.match(‘( q,q ) $’,’(“jan”, “smit”) and a string’,res)
true
res
{‘jan’,’smit’,’and a string’}
res = {}
sip.match(‘( qfirst,q{last} ) $’,’(“jan”, “smit”) and a string’,res)
true
res
{first=’jan’,rest=’and a string’,last=’smit’}
命令行程序与 Lapp
pl.lapp是小而专注的Lua 模块,它的目的是要使标准命令行解析更方便和直观。它实现了 GNU 风格,即以短横线’-‘或长横线’ –’开始的字母。一般带参数的选项期望找到下一个输入作为它的参数 (例如 ’ gcc test.c -o test’),单个短选项可以忽略空格 (例如 ‘head -n4 test.c’ 或gcc -I/usr/include/lua/5.1 …)
Lapp 尽其可能将参数转换为等效的 Lua 类型,即转换数字、文件名转换为文件对象。如果任何转换失败,或缺少所需的参数,则将发出错误消息、 并用文本输出。所以有两个必要的任务,提供的标志和选项的名字,并将它们和类型关联。
对于任何非平凡的脚本,或仅为了个人消遣,有必要提供使用说明。Lapp 的新颖性是定义了松散格式的字符串用法,而且可以指定参数的名称和类型。
示例:
-- scale.lua lapp = require 'pl.lapp' local args = lapp [[ Does some calculations -o,--offset (default 0.0) Offset to add to scaled number -s,--scale (number) Scaling factor <number> (number ) Number to be scaled ]] print(args.offset + args.scale * args.number)
这里是在命令行的会话中使用此脚本:
luascale.luascale.lua:missingrequiredparameter:scaleDoessomecalculations−o,–offset(default0.0)Offsettoaddtoscalednumber−s,–scale(number)Scalingfactor(number)Numbertobescaled lua scale.lua -s 2.2 10
22
$ lua scale.lua -s 2.2 x10
scale.lua:unable to convert to number: x10
….(usage as before)
有两种类型的 Lapp 用法让字符串更有意义。短选项,可以选择其相应的长选项。可遵循括号中的类型说明符。同样,以 ‘<’ PARMETER ’ >’ 开头的参数行,后面跟着的是类型说明符。类型说明符是任一形式’(默认是 ‘VALUE’)’ 或 ‘(’ TYPE’)’ ;默认的说明符意味着选项或参数有默认值,并不是必需的。类型是一个 ‘字符串’、 ‘数’、 ‘文件输入’ 或 ‘文件输出’ ;VALUE是一个数字,(’stdin’、 ‘stdout’、 ‘stderr’) 之一或者是标记。这行的其余不会被分析,可以用作注释。
此脚本在输出表中显示的字段与指定的参数名称之间的关系。
-- simple.lua local args = require ('pl.lapp') [[ Various flags and option types -p A simple optional flag, defaults to false -q,--quiet A simple flag with long name -o (string) A required option with argument <input> (default stdin) Optional input file parameter ]] for k,v in pairs(args) do print(k,v) end
上面显示了args表的所有参数 ;请注意,args.quiet 已经成为为 true,因为它被指定 ;args.p 默认为 false。如果有一个长命名选项,它将在选项中用作局部名称。因为默认的类型是布尔类型,对于简单的标志,它的类型或默认值不是必须的。
$ simple -o test -q simple.lua
p false
input file (781C1BD8)
quiet true
o test
input_name simple.lua
D:\dev\lua\lapp>simple -o test simple.lua one two three
1 one
2 two
3 three
p false
quiet false
input file (781C1BD8)
o test
input_name simple.lua
参数输入已设置为打开的只读文件对象 — — 我们知道它必须是一个只读的文件,因为它是默认值的类型。input_name字段会自动生成 ,因为它经常用来访问原始文件名。
请注意,提供的任意额外参数会放到整数索引表里,即 args [i] ,i表示1 到 #args 之间的值。
对有良好定义和明确任务的短脚本,文件真的不必显式关闭,因为垃圾收集文件对象的结果就是关闭它们。
参考资料:
lua工具库penlight:
http://www.csdn123.com/html/mycsdn20140110/78/78169e2b32e10c2286c9f89aa8ebc2e0.html
Penlight Lua Libraries 1.3.2:
http://stevedonovan.github.io/Penlight/api/index.html
相关文章推荐
- 详解Lua中的表的概念及其相关操作方法
- Lua编程示例(二):面向对象、metatable对表进行扩展
- 修复mysql数据库
- 把Lua编译进nginx步骤方法
- Lua脚本自动生成APK包
- Lua中的元表(metatable)、元方法(metamethod)详解
- Lua中的metatable介绍
- Lua中ipair和pair的区别
- Lua中的函数精讲笔记
- 浅谈Lua的面向对象特性
- 详解Lua中的变量相关知识点
- Lua脚本语言入门笔记
- Lua脚本调用外部脚本
- 详解Lua中的if语句的使用方法
- Lua中调用函数使用点号和冒号的区别
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中强大的元方法__index详解
- Lua中调用C++函数示例
- Lua面向对象之类和继承浅析
- Lua性能优化技巧(一):前言