作者hmml (hmml)
看板mud_sanc
标题[心得] Lua和他快乐的字串函数们...
时间Sun Jun 16 02:36:56 2013
脚本语言Lua可用的字串函数,不限於Mushclient才能用。
整理一下比较好查阅,网路上的还是有点散乱。虽然总体来说
就三种版本贴来贴去的样子。
目 录
┌──────────┬─────────┬─────────────┐
│ 行 名称 │ 行 名称 │ 行 名称 │
├──────────┼─────────┼─────────────┤
│ 19 string.len
│ 46 string.rep
│ 57 string.lower
│
│ 69 string.upper
│ 81 string.sub
│110 string.byte
│
│144 string.char
│176 string.dump
│182 string.find
│
│217 string.match
│250 Lua 的匹配字元
│318 string.gsub
│
│354 string.gmatch
│378 string.format
│422 string.reverse
│
└──────────┴─────────┴─────────────┘
=
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
string.len(s):
功能:返回字串s的长度。
说明:计算一段字串的长度,包含不可见的控制字元。一般送到 Mushclient 画面的内容是
已经被Mushclient解析过的文字,控制字元被解析後移除了, 所以不会算到换
行及色码,
范例:a = string.len('你好吗?')
print (a)
结果会是7。
b,a = '你好吗?',string.len(b)
print (a)
如果先把字串写入b,再代入string.len去计算长度,就不需在b两侧加上''(""也可
以,在lua两者用途相同);如果加上了,b会被视为一个字串, 而非变数,就会
得到值为1。。
如果使用Mushclient 的 trigger,假设匹配的字串:
^(你好吗?)$
执行的内容为:
print (string.len("%1"))
将得到值为7,%1的两侧就必须加上""。
string.rep(s, n)
功能:返回重复n次s的字串。
说明:把字串内容复制n遍,在有需要重复内容输出,但要重复几次不确定的时候,可能会
用到。
范例:a= string.rep(' ',5)
print (a)
重复半形空格五次後显示。
string.lower(s)
功能:将s中的大写字母转换成小写。
说明:用途很单纯,而且只有英文字母才用得到。已经是小写的就不会被转换。因为Lua会
将大小写有差异的两者视为不同的字串或变数,所以还是有用得到的地方。
范例:a,b= 'anD','and'
print (a..' = '..b..'?',a == b)
print (string.lower(a)..' = '..b..'?',string.lower(a) == b)
可以看出差异所在。
string.upper(s)
功能:将s中的小写字母转换成大写。
说明:用途很单纯,而且只有英文字母才用得到。已经是大写的就不会被转换。因为Lua会
将大小写有差异的两者视为不同的字串或变数,所以还是有用得到的地方。
范例:a,b= 'and','and'
print (a..' = '..b..'?',a == b)
print (string.upper(a)..' = '..b..'?',string.lower(a) == b)
可以看出差异所在。
string.sub(s,i,j):
功能:函数撷取字串s的从第i个字元到第j个字元之间的字串。
说明:这个函数用法就比较多元了-
i为正数时,从开头起算;负数则从结尾倒算回去。
j为正数时,意为取到第j个字元,负数时,就是从结尾开始数回去第j个字元。可以
不加,不加的时候,预设值为-1,即取到最後。
有设i才能设j。
范例:a = 'abcdefghijk'
print (string.sub(a,1))
>从第一个字元开始撷取,得:abcdefghijk
print (string.sub(a,2))
>从第二个字元开始撷取,得:bcdefghijk
print (string.sub(a,-1))
>从结尾开始撷取一个字元,得:k
print (string.sub(a,2,-1))
>从第二个字元起撷取,得:bcdefghijk
print (string.sub(a,2,-2))
>撷取第二个字元到倒数第二个字元,得:bcdefghij
print (string.sub(a,-5,-2))
>撷取倒数第五个字元到倒数第二个字元,得:ghij
string.byte(s,i,j)
功能:回传从i到j的字元所对应的数值(ASCII值)。
说明:i预设为1,j预设为i的值。
中文字也可以得到相对的值。
范例:words = 'abcd123测试中!!'
print (string.byte(words,3))
回传变数words里第3个字元"c"的ASCII值:99
print (string.byte(words,3,4))
回传变数words里第3到4个字元"cd"的ASCII值:99 100
print (words:byte(2,5))
回传变数words里第2到5个字元"bcd1"的ASCII值:98 99 100 49
这个语法等同於print (string.byte(words,2,5)),冒号在Lua里可以把右边的值传
递给左边的函数;类似的写法可以在Mushclient的抓聊天讯息到新视窗的Plugin里看
到。
a,b,c = words:byte(2,3)
print (a,b,c)
回传变数words里第2到3个字元"bc"的ASCII值:98 99 nil
这里先把得到的值传到a,b,c里,再用print去显示。当函数回传的值不只一个,但希
望只得到其中一个值,可以这麽写。但一般会如此写:
_,b,_ = words:byte(2,3)
把不需要的值传回变数_。
如果设定的变数名超过回传的值数目,没赋值的变数会显示nil;反之,多余的回传值
会被舍弃。
print (string.byte(words,8,9))
回传变数words里第8到9个字元"测"的ASCII值:180 250
'测'是由两个字元组成的,所以要设头尾以得到两个值。
string.char(...)
功能:回传ASCII值所对应的字元(串)。
说明:把ASCII 码转变回对应字元的函数,有两种输入方式-10位元,直接输入对应
数字;16位元,在数字前加上0x,表示为16位元。使用者数字使用习惯从1开始
不同,电脑从0开始。所以10位元的序列为:
0,1,2,3,4,5,6,7,8,9
16位元则是:
0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
范例:#Send ('say '..string.char(0x1b).."[36mtest")
在输出指令say test,并将test改成青色。
string.char(0x1b)输出控制字元Esc,好让伺服器端
能判读内容带有色码。结果为:
齐格飞(HMML8:剑士)说道:
test
print (string.byte('一',1,2))
回传'一'的ASCII值:164 64
'一'在吃字榜上很有名气,现在看一看这两个字元分别对应什麽字,从值
的大小来看,应是第二个有问题:
print (string.char(164))
得值: ,这个字元不在PcMan的支援下,所以无法显示。
print (string.char(64))
得值:@,刚好是zMUD的表意字元(Mushclient也是)
要组回去,可以用','分隔开一一列举:
print (string.char(164,64))
要输入一连串的值,如上所列般加逗号连接下去即可。
string.dump(function)
功能:返回指定函数的二进位代码(函数必须是一个Lua函数,并且没有上值)。
说明:这个不知道怎麽用。
string.find(s, pattern [, init [, plain]])
功能:寻找s中首次出现pattern的位置,如果找到则回传首次出现的起始和结束位置,否则
返回nil
说明:这个函数有四个参数可用:
s:母体。
pattern:目标字串。
init:搜寻起始位置(数字,可用负值)。可加可不加。
palin:搜寻模式(true|false),开关简单匹配模式。可加可不加,预设为简单匹
配模式。
范例:a = '你的身上(wealth)带有 6667570 影特币,银行存款(balance)有 63908926 影
特币。'
print (string.find(a,'影特币'))
得到:30 35,第一个值是起始位置,第二个值是结束位置。只有抓到第一个'影特币
。如果要抓全部可以增加第三个参数,用回圈执行:
for i = 1,10 do
i,j = string.find(a,'%d+ ',-j)
print(i,j)
if i == nil then break end
end
基本上,这个应该是用while...do...end 或repeat...until,不过,这对初学者而
言(就是我),太危险了,不如用能控制次数的for...end安全。先设一个差不多的
次数,这里是设10次,不管写对还是写错,10就会结束,至少不会死当。把起始值
传给i,结束值传给j,再把j设到string.find的第三个参数,下次就会从上次的结束
寻找位置开始找。这次就不管一样的,改找数字,搜寻条件可以使用也表达式,不过
转义字元不是'\',而是'%'。为了不做白工,所以加个判断,找完之後就自行跳出回
圈。结果如下:
第一组数字起始位置:22,结束位置:29。
第二组数字起始位置:58,结束位置:66。
"nil nil"代表己经找到最後了。
string.match(s,pattern[, init ])
功能:回传目标字串中和模式字串匹配的部分。
说明:也就是从s中,找出和pattern条件相符的部份并回传,和string.find一样,它只会
匹配一次,找到一个就会停止动作,但可以选择开始匹配的位置,只要在末尾在加上
一个参数即可。这个函数的重点在於表示式匹配,毕竟一模一样的字串被匹配出来回
传,并没什麽意义。所以主要是用在找相同格式的字串。
范例:a = '你的身上(wealth)带有 6667570 影特币,银行存款(balance)有63908926 影特
币。'
print (string.find(a,'影特币%S%S'))
找出前缀'影特币',後面两个字元长度的非空白字串相匹配的字串,得到第一个值:
影特币,
print (string.match(a,'影特币%S%S',38))
找出前缀'影特币',後面两个字元长度的非空白字串相匹配的字串,但是从第38个字
元找起,得到第二个值:影特币。
实际上应该是找金额比较实用,透过匹配条件的设定,可以一次找两个:
print (string.match(a,'(%d+) %S+ (%d+)'))
匹配前後都是数字组的字串,用()可以单独取出需要的部份,得到值:
6667570 63908926
如果想指定取某个值,同样:
i,j = string.match(a,'(%d+) %S+ (%d+)')
或
i,j = a:match('(%d+) %S+ (%d+)')
皆可。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Lua 的匹配字元
┌─┬─────────────────────────────────┐
│.
│ 所有字符
│
│%a│ 字母,包含大小写。 │
│%c
│ 控制字符,如:ESC、换行等不可视字元大多都是。
│
│%d│ 数字,0-9,以外的都不是。 │
│%l
│ 小写字母,大写字母和非字母都不算。但是%L并不等於%u。
│
│%p│ 标点符号,只有算单字元的那些,双字元的都不算。 │
│%s
│ 空白字符。这个还蛮常用的,对非英语语系来说。
│
│%u│ 大写字母,小写字母和非字母都不算。但是%U并不等於%l。 │
│%w
│ 字母和数字字符。
│
│%x│ 十六进制数字。就当做是0-9加上a-f的集合。 │
│%z
│ 内部表示为0的字符,这个不知何时用到。
│
└─┴─────────────────────────────────┘
以上这些都可以单独使用,去做匹配,除了第一个外,将其它的匹配字元小写改成大写,就
会将功能反转,如:%a 代表所有字母;而%A就是非字母。%c是匹配所有控制字元,%C就是
所有非控制字元。
另外,还有一些加强匹配效果的字元,有点主词+形容词的味道:
( ) % + - * ? [ ] ^ $
():用来补获符合条件的字串内容,如果要将它做为匹配的条件之一,请在前方加上%。
%:转义字元,用来告诉程式後面的字元,是字串的一部份,还是匹配用的字元,但本身就
是特殊用途的字元,加上它,就变成一般的字元。如果需要匹配%,为了让它变一般的字
元,在前方加上%。如有一个字串'100%',要写出符合条件的表达式,像这样:
%d+%,因为末尾的%尚未被转义,会视为跟第一个%相同作用,造成表达式本身错误,正
确要这麽写%d+%%。
+:它是一种後缀字元,用来设定匹配字元的长度条件,表示这个匹配字元有多长,+代表1
个或更多,如%d+,代表这组数字至少为一位数,它匹配:"12","0","324567546"...等
。
-:同上,但条件为0或更多,跟*不同的地方是-为最少匹配,*为最多匹配。如:
print(string.match(1234567890,"(%d+)(%d+)"))
前方的%d+会取到能让表达式匹配成功的极限,得结果:123456789和0
print(string.match(1234567890,"(%d-)(%d+)"))
前方的%d-即使不取值,也能匹配,将所有数值都让给%d+,得:""和1234567890
""不代表它匹配失败,它有取到值,不是nil
print(string.match(1234567890,"(%d*)(%d+)"))
前方的%d*会取到能让表达式匹配成功的极限,得结果:123456789和0
*:同上,但条件为0或更多,其它前一条讲完了。
?:条件是0或1个。模式是最大匹配,跟*相同,只是当?占先手时,最也多取一位数,*占先
手时,会取到让後手满足匹配的最底限为止。
[]:是一个集合,你可以把你要匹配的内容放进去,但要记住,它匹配的长度依然是一个字
元,要设定匹配的长度,请加"*","+","-","?",如:
[0-9]:匹配数字,相等於%d
[0-9a-z]:匹配数字和英文字母小写。
[-a-z]:匹配"-"和英文字母小写。
[%d%a]:匹配英数字,等同%w。
[%d\n]:匹配数字和换行。
^:前缀,为匹配字元加上开头限定的条件。但如在[]里的开头,就变成反集合。如:
[\n]匹配换行字元,[^\n]匹配换行字元以外的字元。
$:後缀,为匹配字元加上末尾限定的条件,但要注意看不到的字元,如'\n','\r'可能会影
响结果。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
string.gsub(s,pattern,repl [, n])
功能:将目标字串中和模式字串匹配的部分全部取代後回传。
说明:有四个参数:
s:母体
pattern:匹配条件
repl:新的内容
n:取代次数。
它会回传两个值,一个是取代後的结果,一个是取代次数。
同样支援表达式匹配。
范例:a = '你的身上(wealth)带有 6667570 影特币,银行存款(balance)有63908926 影特
币。'
i,j = string.gsub(a,'%d+ %S%S%S%S%S%S','30块新台币')
print (i)
print ('替换次数:'..j)
得结果:
你的身上(wealth)带有 30块新台币,银行存款(balance)有30块新台币。
替换次数:2
i,j = string.gsub(a,'%d+ %S%S%S%S%S%S','30块新台币')
print (i)
print ('替换次数:'..j)
得结果:'
你的身上(wealth)带有 30块新台币,银行存款(balance)有63908926 影特币。
替换次数:1
print(string.gsub("hello Lua","(.)(.)","%2%1"))
将相邻的两个字符对调,输出为ehll ouLa
这个是在别旳地方看来的,不过以MushClient的别名输出,结果不太一样,但在命令
列输出是正确的。
print(string.gsub("hello Lua!","%a","%0-%0"))
输出为h-he-el-ll-lo-o L-Lu-ua-a!
string.gmatch (s, pattern)
功能:回传所有目标字串中和模式字串匹配的部分。
说明:和string.sub/gsub不同(功能截然不同),加上g,基本功能也是一样,不过
string.gmatch会寻找匹配部份,从头找到尾,它只有两个参数,直接用print输出,
只会得到一个table表的ID值。必须用回圈才会取出内容。
范例:s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
找出所有单字并输出。如果gmatch的回圈老是写失败,找不到问题,直接用上例,这
个Lua说明手册的范例去修改。网路上有几个例子的教学,不过在Mushclient都无法
执行,这个是目前找到成功的。
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
把指定格式的字串取出,写到一个表中。因为匹配的捕获有两个,所以回圈的变数增
加为两个。
string.format (formatstring, ···)
功能:将字串格式化後再回传。
说明:这个相对其它字串函数,使用方式比较复杂,建议是一边改一边输出检查结果。它有
两个参数:
formatstring:显示的格式。
string:字串内容。
设定格式的转义码也是用%,要注意大小写,内容有:
┌───┬─────────────────────────────────┐
│%c
│接受一个数字,并将其转化为ASCII码表中对应的字元
│
│%d,%i │接受一个数字并将其转化为有符号的整数格式,如果数字是为16进位的格 │
│ │式(如0xf),会被转成10进位的数字,但起始值是以0起算的。 │
│%o
│接受一个数字并将其转化为八进制数格式
│
│%u │接受一个数字并将其转化为无符号整数格式 │
│%x
│接受一个数字并将其转化为十六进制数格式, 使用小写字母
│
│%X │接受一个数字并将其转化为十六进制数格式, 使用大写字母 │
│%e
│接受一个数字并将其转化为科学记数法格式, 使用小写字母e
│
│%E │接受一个数字并将其转化为科学记数法格式, 使用大写字母E │
│%f
│接受一个数字并将其转化为浮点数格式
│
│%g(%G)│接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式 │
│%q
│接受一个字符串并将其转化为可安全被Lua编译器读入的格式
│
│%s │接受一个字符串并按照给定的参数格式化该字符串 │
└───┴─────────────────────────────────┘
在%和匹配字元中间,依规则增加格式化的条件:
%[+-(一般是靠左或靠右)][补位字元,几乎只能用0][总宽度].[取几个位元][字符]
如:%+06.3s << 靠右,总宽度6位,目标字串只取3个字元长度。在%和s外面则被视
为普通字串。
范例:string.format("%%c: %c", 83) 输出S
string.format("%+d", 17.0) 输出+17
string.format("%05d", 17) 输出00017
string.format("%o", 17) 输出21
string.format("%u", 3.14) 输出3
string.format("%x", 13) 输出d
string.format("%X", 13) 输出D
string.format("%e", 1000) 输出1.000000e+03
string.format("%E", 1000) 输出1.000000E+03
string.format("%6.3f", 13) 输出13.000
string.format("%q", "One\nTwo") 输出"One
Two"
string.format("%s", "monkey") 输出monkey
string.format("%10s", "monkey") 输出 monkey
string.format("%5.3s", "monkey") 输出 mon
string.reverse (s)
功能:将字串的排列顺序倒过来并输出。
说明:如上。
范例:免了。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.132.196.45
1F:→ hmml :值3P币... 06/16 02:37
※ 编辑: hmml 来自: 220.132.196.45 (06/16 02:55)
※ 编辑: hmml 来自: 220.132.196.45 (06/16 03:13)
※ 编辑: hmml 来自: 220.132.196.45 (06/16 13:03)