(转)LUA正则表达式不完全指南
转⾃剑侠,并稍微修改个别⽂字。
好不容易闲下来,研究了⼀下正则表达式,然后越钻越深,经过跟⼤神们讨论学习后,就没有然后了。总之╮(╯▽╰)╭很有⽤的⼀个东西,⾄少对于⽤户输⼊的读取⽅⾯会⽐较⽅便,所以就简单举例说说。
注:正则这个⽐较不好理解,经常容易转不过弯来,个⼈觉得最好的学习⽅式就是⾃⼰去试,举⼀反三,才会知道错在哪⾥,我尽量提供不同种类同样⽤法的例⼦⽅便理解。
正则表达式使⽤单个字符串来描述、匹配⼀系列符合某个句法规则的字符串。在很多⽂本编辑器⾥,正则表达式通常被⽤来检索、替换那些符合某个模式的⽂本。(好吧,这是百度来的)
简单来说就是按照⼀定想法获取与替换字符串。想怎么换就怎么换(真的( ⊙o⊙ )?)
⽇常运⽤的时候,会遇到的情况⽐如某段话⾥带有关键字,多个关键字等
“⽇常⼤战xxx来”,“收xxx,带价密”
这时候捕获这些字符串下来进⾏分析与记录,让你不⾄于错过某些不应该错过的,或者说⾃动密那个⼈预定位置什么的……嗯,好像扯远了,那是插件,今天只说lua。
元字
符
描述
. 匹配任意字符,包括中⽂、字母、数字、符号等
%特殊符号转义,例如:%.为匹配点,%%为匹配百分⽐符号,跟“\”⽤来转义引号是⼀样的
%a alphabet,匹配字母,⼤⼩写都匹配,%A为匹配除字母外其他字符
%b bisymmetric,匹配对称字符,%bxy,x为开始匹配字符,y为结束匹配字符,xy可随意指定。例如:%b<>为匹配包括<>在内的所有字符
%c control character,匹配控制字符,详见百度,%C为匹配除控制字符外其他字符
%d digit,匹配数字,0到9,%D为匹配除数字外其他字符
%l lower case,匹配⼩写字母a-z,%L为匹配⼩写字母外其他字符
%p punctuation,匹配标点符号,%P为匹配标点符号外其他字符
%s space,匹配空⽩符号,包括\t(tab键四格空⽩),\n(新⾏的标⽰),\r(换⾏的标⽰),%S为匹配空⽩符号外其他字符
%u upper case,匹配⼤写字母A-Z,%U为匹配⼤写字母外其他字符
%w words,匹配字母和数字,%W为匹配字母和数字外其他字符
%x hex,匹配⼗六进制数字,%X为匹配⼗六进制数字外其他字符
%z zero,匹配代表0的字符,%Z为匹配0字符外其他字符
()匹配与返回括号内的内容,例如:123(.+),匹配与返回带有123字样后续内容。详见下
[]⾃定义匹配字符集,例如:[a-z0-9,%.]匹配a到z以及0-9还有逗号,百分⽐号跟点,[^a-z0-9,%.]匹配除字符集以外的其他字符+匹配前⼀字符1次或多次,常⽤于连贯性字符,例如:%a+ 以单词为单位匹配
*匹配前⼀字符0次或多次,最长匹配,常⽤于匹配空⽩符,例如%s*,将会匹配字符串内所有单个或者连贯空格
-匹配前⼀字符0次或多次,最短匹配,在进⾏所有字符匹配时匹配最短,例如:|123|456|,⽤|(.*)|则会返回123|456,⽽|(.-)|则只返回123
?
匹配前⼀字符0次或1次,例如:匹配正负数字,因为正数不带负号
^匹配开头,例如:^%d+为以数字开头的匹配,可与匹配结尾⼀同使⽤$匹配结尾,例如:%d+$为以数字开头的结尾,可与匹配开头⼀同使⽤
常⽤string操作:
参考资料:
string.find(s,pattern[,init[,plain]])
匹配第⼀个符合条件的项⽬的起始位置与终⽌位置,如果没到则返回nil
s代表⽬标字符串
pattern代表你要匹配的规则,见上⾯正则表格
init代表开始匹配的位置,默认为1,可以是负数,可不填
plain布尔值,如果为true时,则执⾏匹配任何匹配规则不⽣效,只是简单的字⾯匹配
s = "%d+002929aciwe%a+cqoe01230"
local x,y = string.find(s,"%d+",1) --匹配数字,⼀次或多次连续
print(x,y)
--> x = 4, y = 9
s = "%d+002929aciwe%a+cqoe01230"
local x,y = string.find(s,"%d+",10) --匹配数字,⼀次或多次连续
print(x,y)
--> x = 22, y = 26
s = "%d+002929aciwe%a+cqoe01230"
local x,y = string.find(s,"%d+",1,true) --匹配字符"%d+"
print(x,y)
--> x = 1, y = 3
s = "%d+002929aciwe%a+cqoe01230"
local x,y = string.find(s,"%a+",1) --匹配字母,⼀次或多次连续
print(x,y)
--> x = 2, y = 2
s = "%d+002929aciwe%a+cqoe01230"
local x,y = string.find(s,"%a+",1,true) --匹配字符"%a+"
print(x,y)
--> x = 15, y = 17
string.match(s,pattern[,init])
匹配第⼀个符合条件的项⽬
s代表⽬标字符串
pattern代表你要匹配的规则,见上⾯正则表格
init代表开始匹配的位置,默认为1,可以是负数,可不填
s = "1number123xyz"
x = string.match(s,"%d+",1) --匹配数字,⼀次或多次匹配,从第⼀号位开始
-->x = 1 --返回值是1
x = string.match(s,"%d+",2) --匹配数字,⼀次或多次匹配,从第⼆号位开始
-->x = 123 --返回值是123
x = string.match(s,"%d+",-4) --匹配数字,⼀次或多次匹配,从右起第四号位开始向右
-->x = 3
x = string.match(s,"%d+",-3) --匹配数字,⼀次或多次匹配,从右起第三号位开始向右
-->x = nil
x = string.match(s,"%d*",-3) --匹配数字,零次或多次匹配,从右起第三号位开始向右
--> 完成匹配,返回空⽩
返回迭代器,每次调⽤时会返回符合条件的项⽬和迭代器,如果没有指定条件,返回整个字符串。s代表⽬标字符串
pattern代表条件
s = "1number123xyz"
for x atch(s,"%d+") do --匹配数字,⼀次或多次
print(x)
end
--> x = 1, x = 123
s = "1number123xyz"
for x atch(s,"%d-") do --匹配数字,0次或多次,最短匹配,即0次
print(x)
end
-->完成匹配,返回空⽩
s = "1number123xyz"
for x atch(s,"%d*") do --匹配数字,0次或多次,最长匹配
print(x)
end
-->1 123 --中间为空⽩
t = {}
s = "hello=123, lua=456"
for k,v atch(s,"(%w+)=(%w+)") do --匹配等号两边的数字与字母⼀次或多次,并且分别返回括号内的两个值
t[k]=v
print(k,v)
end
--> hello 123
lua 456
--> t= {["hello"]="123",["lua"]="456"}
string.sub(s,i[,j])
返回⼀项字符串的⼀部分
s为⽬标字符串
i为起始位置
j为终⽌位置,可不填,默认为-1,即使字串结束
i,j都可为负数
s = "我们是快乐的⼈啊!23333"
local x = string.sub(s,1,-6)
--> x="我们是快乐的⼈啊!"
重点介绍,最常⽤的
string.gsub(s,pattern,repl[,n])
返回因符合规则被全部或替换n次后的字符串,同时返回匹配成功次数
s为⽬标字符串
pattern为规则
repl为替换字符串,可为string,function,table。如果为string,则%在这⾥作为⼀个特殊符号,任何%1到%9代表会第
⼏次的返回值(这个返回值是⼀次匹配成功值下⾯会介绍),%1就是第⼀个值,%9则是第九个。⽽%0则是全部。⽽%%则表⽰百分⽐字符。如果repl是function,每次匹配成功将会调⽤函数,会将匹配到的字符串变为参数,如果没有指定规则,则将整个字符串传为⼀个参数。如果rep是table,则每次匹配成功都会与table进⾏⽐对,如符合array则替换为key值,如没有规则,则以整个字符串作为⽐对。注:如果function和table的返回值是string或者数字,那么则替换,如果返回false或者nil则不进⾏替换。
n为执⾏⼏次替换
s="先来最基础简单的"
x = string.gsub(s,"基础简单","复杂困难") --将"基础简单"替换成"复杂困难"
--> x = "先来最复杂困难的"
s="多次替换数字123,多次替换数字321"
x = string.gsub(s,"%d+","lalala") --将数字替换成"lalala"
--> x = "多次替换数字lalala,多次替换数字lalala"
s="本末&倒置,开始=逆转"
x = string.gsub(s,"(.+)&(.+),(.+)=(.+)","%3%2%4%1") --⼀次匹配下返回括号内四个值,并且排列后替换整个字符串
--> x = "开始倒置逆转本末"
%1-%4相当于临时变量,将临时变量赋予括号内的值并且将整个字符串替换成临时排列后的变量。
%1 = 本末,%2 = 倒置,%3=开始,%4=逆转,⽽%0则是等于整个字符串:本末&倒置,开始=逆转
s="hello string test world"
x = string.gsub(s,"(%w+)%s*(%w+)","%1",1) --⼀次匹配返回两个值,将这两个替换成第⼀个值,只执⾏⼀次
--> x = "hello test world"
由于(%w+)%s*(%w+) 是匹配两个单词为⼀对,那么在例⼦⾥⾯符合条件的有两对,⼀个是hello string以及test world。⾸先匹配到hello string返回两个
值%1=hello,%2=string,然后将整个hello string替换成hello。⽽由于值执⾏⼀次,所以第⼆对匹配成功的则不进⾏替换
s="hello string test world"
x = string.gsub(s,"(%w+)%s*(%w+)","%0 %0",1) --匹配成功后将多复制⼀次,只执⾏⼀次
--> x = "hello string hello string test world"
匹配成功的是hello string,两个%0代表这个hello string会出现两次,也就是这个结果了。
pattern为函数的,如下例:
function a(s)
return loadstring(s)()
end
x = string.gsub("2+6 = $return 2+6$", "%$(.-)%$",a)
--> x = "2+6 = 8"
pattern为table的,如下例:
local t = {name="lua", version="5.1"}
x = string.gsub("$name-$", "%$(%w+)", t) --匹配table内的项⽬并且替换掉原有的
-
-> x="lua-5."
说了这么半天,正则主要是看怎么定下规则,其他的应⽤都听简单的,⾄于规则的熟悉则要多练习,多实验才能体会到。
实际范例:
⽂本 = 我切,我切|我切。我切@我切切切
规则 = [^,。@|]+
结果 = 我切我切我切我切我切切切 (gmatch)
⽂本 = 讨厌的空格T _ T
规则 = %s*
结果 = 讨厌的空格T_T (gsub)
正则匹配是什么⽂本 = a=3,不作死=就不会死。你要怎么=列表
规则 = ……你居然想⼀步把这个分开,果然作死
第⼀步:⽤%s*去掉所有空格
第⼆步:将分隔符去掉利⽤"切切范例"
第三步:将等号去掉并为table导⼊键值
结果 = {[a]=3,["不作死"]="就不会死",["你要怎么"]="列表"}
遇到不能⼀次分开的可以进⾏多次分割,若是动态⽂本则最好先转⼀个固定的格式。基本上处理字符串先是要格式⽐较好,后续处理才⽐较简单。⾄于-*+这三个的区别⽤处得多熟练,因为这三个很相似,所以很容易搞乱= =实在弄不清楚开SCITE去试试╮(╯▽╰)╭
愉快的⼀天⼜过去了╮(╯▽╰)╭
什么!居然写了⼀天!?o(>﹏<)o
我的⼩结:
match到的内容,find到的结果,sub⼦串
函数名前有g表⽰全局,即对整个字符串处理,分割字符串可以⽤string.gsub。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论