lua工具库penlight--03字符串

字符串提取函数

这些方法也是从Python借鉴来的,但索引从1开始。stringx定义了一些函数如isalpha和isdigit,
用来判断字母和数字;startswith和endswith可以方便用来查找子串(endswith可以用来判断后缀
,如f:endswith{'.bat','.exe','.cmd'});还有对齐方法just和除去空白符的strip。
 > stringx.import()
> ('bonzo.dog'):endswith {'.dog','.cat'}
true
> ('bonzo.txt'):endswith {'.dog','.cat'}
false
> ('bonzo.cat'):endswith {'.dog','.cat'}
true
> (' stuff'):ljust(20,'+')
'++++++++++++++ stuff'
 > ('  stuff '):lstrip()
'stuff '
 > ('  stuff '):rstrip()
 '  stuff'
 > ('  stuff '):strip()
'stuff'
> for s in ('one\ntwo\nthree\n'):lines() do print(s) end
one
two
three
 
此文还有许多其它威力强大的函数。
 
字符串模板
从python里还借鉴了字符串替换模板。
 local Template = require ('pl.text').Template
 t = Template('${here} is the $answer')
 print(t:substitute {here = 'Lua', answer = 'best'})
 ==>
 Lua is the best
 
"$ var"或者"${var}",可以用来连接文本,如果var没找到会抛出错误,safe_substitute函数则不会。
另外还有一个 indent_substitute可以方便的插入大块文本。这个函数提供了缩进。
 local Template = require ('pl.text').Template
 
t = Template [[
     for i = 1,#$t do
         $body
     end
]]
 
body = Template [[
local row = $t[i]
for j = 1,#row do
     fun(row[j])
end
]]
 
print(t:indent_substitute {body=body,t='tbl'})
 
And the output is:
for i = 1,#tbl do
     local row = tbl[i]
     for j = 1,#row do
         fun(row[j])
     end
end
 
indent_substitute可以替换模板,这样参数本身可以被替换,所以$t被替换了两次。
 
pl.text还有dedent函数,用来出去多行字符串里的缩进(换行符之类的)。wrap函数可以
把传入的长字符串根据宽度转换为字符串表。indent用来切割多行字符串。
 
在Penlight 0.9里提供了text.format_operator,采用了Python风格的字符串格式化符%
> text.format_operator()
> = '%s[%d]' % {'dog',1}
dog[1]
它比string.format更简洁,通过用命名域还可以扩展$变量。
 
> = '$animal[$num]' % {animal='dog',num=1}
dog[1]
 
导入stringx.import后你要注意所有的strings共用相同的元表,不过在你的代码里你可以放心的
用提供的函数。
 
另一种风格的模板
另外一个模块是template(t小写),模仿自Rici Lake的Lua Preprocessor。它允许你把lua代码
和模板混合在一起。只有两条规则:
1、已#开头行的是lua代码
2、其它用$()包围的是lua表达式
如下一个生成html的模板如下:
<ul>
# for i,val in ipairs(T) do
<li>$(i) = $(val:upper())</li>
# end
</ul>
假设上面的文本在tmpl里,可以按如下方式展开模板:
local template = require 'pl.template'
res = template.substitute(tmpl,{T = {'one','two','three'}})
将会生成
<ul>
<li>1 = ONE</li>
<li>2 = TWO</li>
<li>3 = THREE</li>
</ul>
有一个简单的函数,template.substitute,它有两个参数模板字符串和环境表。环境表可以包含
一些特殊的域,如_parent 可以设置‘fallback’环境以防某个符合没找到。_brackets表示'()',_escape
表示'#'。有时候当处理重量级语言时,需要重定义这些接口,如$(V)在Make里有其它意义,#在
C/C++里表示预处理符。
 
最后,如果出错了,可以传入_debug产生lua代码dump。例如C代码生成。
local subst = require 'pl.template'.substitute
 
local templ = [[
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
 
> for _,f in ipairs(mod) do
static int l_$(f.name) (lua_State *L) {
 
}
> end
 
static const luaL_reg $(mod.name)[] = {
> for _,f in ipairs(mod) do
     {"$(f.name)",l_$(f.name)},
> end
     {NULL,NULL}
};
 
int luaopen_$(mod.name) {
    luaL_register (L, "$(mod.name)", $(mod.name));
     return 1;
}
]]
 
print(subst(templ,{
     _escape = '>',
     ipairs = ipairs,
     mod = {
         name = 'baggins';
         {name='frodo'},
         {name='bilbo'}
     }
}))
 
文件I/O风格的字符串
pl.stringio提供了三个函数; stringio.open处理传入的字符串,返回文件的对象供读写。
它提供了read方法,参数和标准文件对象一样。
 > f = stringio.open 'first line\n10 20 30\n'
> = f:read()
first line
> = f:read('*n','*n','*n')
 10    20    30
同样也支持lines和seek.
stringio.create 可以创建一个可写的类文件的对象。现在你可以使用write写字符串流。
最后可以使用value提取字符串。这个’string builder‘模式可以方便创建大字符串。

 原文:http://stevedonovan.github.io/Penlight/api/topics/03-strings.md.html

posted @ 2014-03-08 20:13  半山th  阅读(680)  评论(0编辑  收藏  举报