[lua]紫猫lua教程-命令宝典-L1-01-09. string字符串函数库

L1[string]01. ASCII码互转

小知识:字符串处理的几个共同的几点

1.字符串处理函数 字符串索引可以为负数 表示从字符串末尾开始算起 所有字符串处理函数的 字符串索引参数都使用

2.所有的字符串处理函数 其实可以用另外一种形式来显示  面向对象的方式  把string 看作是一个类  该类下面存在很多 类方法 比如string.sub string.char 等等  每个字符串其实都可以看作是string类的一个实例 所以 我们可以使用 这样的形式来调用字符串处理函数   如下面的形式

yy="test"
print(yy.byte(yy))--正常是string.byte(yy) 不过看到这个形式也不要认不出来

3.string字符串处理库 并不支持汉字  需要的话去看5.3独有的utf8库


小知识:ASCII转换

2个函数

string.byte()和string.char() 可以把数字和字符 以ascII的对应关系相互转化


个人理解的几个常见的用处

math.randomseed(os.time())
--依次输出a-z字母
for i=string.byte("a"),string.byte("z") do
    print(string.char(i))
end
--配合随机函数随机输出字母
print("======================")
for i=1,10 do
    print(string.char(math.random(string.byte("a"),string.byte("z"))))
end
--可以输出一些不太常见或者不太好输出的字符
--"fdsd\"dsf123" 比如这个中间的双引号(双引号在ascII 编号是34)  我们可以用\转义一下避免报错 其实也可以用string.char()
print("fdsd\"dsf123")--去掉双引号的歧义
print("fdsd\034dsf123")--字符串转义字符\034代表aSCII的双引号
print("fdsd" .. string.char(34) .. "dsf123")


注意:string.byte() 第二个参数是从哪个字符开始转化 第三个是转化结束位置  一旦要转化的字符不存在 或者存在问题 会返回nil 这个要注意 这个函数并不是一定会返回数值 使用它注意判断nil的情况 切记

string.char()也是可以同时转化多个 没什么可说的 但是一旦string.char()参数值超出了ASCII的编码上限 它会直接报错 连返回nil的机会都没。。lua果然是很久以前的语法 在严谨程度上还是不够啊

x1,x2,x3,x4=string.char(97,98,99,100)—a,b,c,d


L1[string]02. 查找与截取字符串

1.string.find() 查找 

找到了返回位置 返回2个数值 第一个表示找到字符串开头位置 第二个是结尾位置 找不到返回nil 并且支持正则  真是老语法 果然逻辑还是不完美

其实找不到可以返回-1  这样都返回数值 在判断返回值和比较的时候就铁定不会报错 万一返回nil 要和其他数值比较就直接崩溃了代码 等后面想想把string.find()重构一下 等后面再说

可以考虑每次string.find的结果 处理一下

yy="sdfwerew213dfw2134ds23dfs324dsfr2423"
temp,temp2=string.find(yy,"2113")
temp=temp or -1
temp2=temp2 or -1


2.string.sub(str,i,j) 截取

常见用法

string.sub(str,1,j)--从开头开始取长度为j的子字符串

string.sub(str,-j)-从末尾倒取长度为j的字符串

从尾部取

yy="sdfwerew213dfw2134ds23dfs324dsfr2423"
temp=string.sub(yy,-4,-1)
temp=temp or ""--为了避免结果为nil 取不到就返回一个空字符串就好 何必是nil
print(temp)

第二个参数不会小于1 也不会超出整个字符串长度 如果小于或者超出了就回归1

第三个参数不写默认为-1  写了但是超出了字符串本身的长度 则恢复默认为字符串长度



3.string.gsub() 替换 相当于按键的replace 但是功能更加的强大

支持正则表达式 并且最后那个参数支持自定义函数 功能非常强大  不过这里我们就不多说了  下面就是用string.gsub构成的分割函数

function string.split(s, p)    
    if s == nil then
        return nil;
    end    
    if p == nil then        
        return s;    
    end    
    local rt= {};    
    s = tostring(s);    
    string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end );    
    return rt;
end


4.string.match() 匹配

好吧 还是匹配不到就返回nil 所以我还是想等过段时间重载这个函数

yy="sdfwerew213fsdfw2134ds23dfs324dsfr24fs23"

temp=string.match(yy,"f12s")
temp=temp or "" --还是如果匹配不到就返回空字符串就可以了
print("[" .. temp .. "]")

匹配结果规则

如果pattern里面没有括号存在 那么会按照正则表达式匹配出 整个字符串 如果pattern里面存在括号 那么就显示括号匹配的内容 而不显示整个pattern匹配得整个字符串了

local strContent = [[abcde  csdn = {博客}  csdn.net]] 
local strPattern = [[^(.*)(csdn%s*=%s*)(%b{})(.*)$]] 
--local strPattern = "^.*csdn%s*=%s*%b{}.*$"
local strCapture1, strCapture2, strCapture3, strCapture4 = string.match(strContent, strPattern)
print(strCapture1, strCapture2, strCapture3, strCapture4)--abcde      csdn =     {博客}      csdn.net


5 string.gmatch() 匹配出全部符合要求的 返回得是一个迭代器(类型其实是个function) 而不是string.match()那样得 而且迭代器返回的不一定是一个变量

--从网页源码提取出手机号码和对应的账号信息
local str = [[
<li class="flexs flex-column li_root" name="one" num="15306314623">第1个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314624">第2个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314625">第3个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314626">第4个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314627">第5个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314628">第6个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314629">第7个账号</li>
<li class="flexs flex-column li_root" name="one" num="15306314630">第8个账号</li>

]]
--设置pattern
local strPattern=[[name="one" num="(1[3-9]%d%d%d%d%d%d%d%d%d)">(.-)</li>]]--使用[[]]构建pattern注意写完后输出一下看看构建的pattern是否满足自己的要求
print(strPattern)
print(string.match(str,strPattern))
--遍历输出所有匹配到的内容
for v,k in string.gmatch(str, strPattern) do
    print(v,k)
end


结果

name="one" num="(1[3-9]%d%d%d%d%d%d%d%d%d)">(.-)</li>
15306314623    第1个账号
15306314623    第1个账号
15306314624    第2个账号
15306314625    第3个账号
15306314626    第4个账号
15306314627    第5个账号
15306314628    第6个账号
15306314629    第7个账号
15306314630    第8个账号
程序于 0.26 秒完成 (pid: 14924).




知识点:lua正则的相关知识

https://blog.csdn.net/fightsyj/article/details/83615498  比较详细的正则资料  包含元字符 各种元字符例子 和4个正则相关的函数 实现查找 替换匹配

lua下正则的几个特别之处

1.%b  

匹配对称字符,一般写法为"%bxy",x为开始匹配字符,y为结束匹配字符,xy可随意指定
例如:"%b<>"为匹配包括<>在内的所有字符 %b后面只能跟2个符号 无法跟多个

2.-

最小匹配 就是常见的懒惰匹配符号-

str = "ab12345ed"

print(string.match(str, "%d-"))  --空字符串 注意-单独使用的时候 它可以代表0次和多次 最少是代表0次 并且是最小匹配 自然就是0次  不要单独使用他   没有什么意义

3 lua的正则和一般正则而言缺少的元字符 |  和 {}   

一个表示选择的| 另外1个是表示重复数量的{}  在lua正则下 | {} 不是元字符切记

--匹配出手机号码

str = "qsasd15166158515asdaf"
print(string.match(str, "1[3-9]%d%d%d%d%d%d%d%d%d"))  -- 15166158515

print(string.match(str, "1[3-9]%d{9}"))  -- nil  因为lua的元字符里面没有{}设置重复次数

4 去掉两边空格 还有检测是否是数值是否是字符串 是否是空格等等常见用法 属于一般的用途 正则是个需要不断练习和测试的积累 不过每次写lua正则 建议先看一遍lua的元字符

function testlib:trim (s)
   return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end



L1[string]03. 转大小写与重复字符

6.string.rep() 获取重复N个的字符串

print(string.rep("hello",10))—hellohellohellohellohellohellohellohellohellohello


7 string.reverse() 逆转字符串 没什么说的

8 string.lower  string.upper

9 string.len() 推荐用#获取字符串长度 和 数字索引表的长度

L1[string]04. 格式化字符串

string.format()

注意 %d %s 对应的变量 这些变量一定要检测是不是对应的变量类型  如果对应的变量类型不符合 就会代码报错崩溃

%d是代表0-9的整数  不包含小数点  而且可以控制数字的长度 比如

x=14   string.format(“x=%3d”,x)--x=14

x=14   print(string.format("x=%5d",x))x=   14 --14前面多了3个空格

%f 表示小数 而且可以控制小数点位数 %.2f 表示保留两位小

%s 表示字符串 用法没什么说的

%x 会自动把对应的数字转化为十六进制显示 一般永不打上

%X    - 接受一个数字并将其转化为大写的十六进制格式


注意 这个和正则元字符不是一个东西 不要混淆了


注意:会根据情况自动内部转化类型 除非无法转化才会崩溃 为了避免这个情况  可以这样处理

x=10

y=11

z=12

print(string.format("x=%s,y=%s,z=%s",tostring(x),tostring(y),tostring(z))) --这样都转化为字符串 匹配字符串里面都是%s  可以避免报错崩溃

posted @ 2019-07-18 21:20  点-滴  阅读(379)  评论(0编辑  收藏  举报