(转)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操作:
参考资料:http://www.lua.org/manual/5.1/manual.html
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) --匹配数字,零次或多次匹配,从右起第三号位开始向右找
--> 完成匹配,返回空白
string.gmatch(s,pattern)
返回迭代器,每次调用时会返回符合条件的项目和迭代器,如果没有指定条件,返回整个字符串。
s代表目标字符串
pattern代表条件
s = "1number123xyz"
for x in string.gmatch(s,"%d+") do --匹配数字,一次或多次
print(x)
end
--> x = 1, x = 123
s = "1number123xyz"
for x in string.gmatch(s,"%d-") do --匹配数字,0次或多次,最短匹配,即0次
print(x)
end
-->完成匹配,返回空白
s = "1number123xyz"
for x in string.gmatch(s,"%d*") do --匹配数字,0次或多次,最长匹配
print(x)
end
-->1 123 --中间为空白
t = {}
s = "hello=123, lua=456"
for k,v in string.gmatch(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-$version.tar.gz", "%$(%w+)", t) --匹配table内的项目并且替换掉原有的
--> x="lua-5.1.tar.gz"
说了这么半天,正则主要是看怎么定下规则,其他的应用都听简单的,至于规则的熟悉则要多练习,多实验才能体会到。
实际范例:
文本 = 我切,我切|我切。我切@我切切切
规则 = [^,。@|]+
结果 = 我切 我切 我切 我切 我切切切 (gmatch)
文本 = 讨 厌的 空格T _ T
规则 = %s*
结果 = 讨厌的空格T_T (gsub)
文本 = a=3, 不作死=就不会死。 你要怎么=列表
规则 = ……你居然想一步把这个分开,果然作死
第一步:用%s*去掉所有空格
第二步:将分隔符去掉利用"切切范例"
第三步:将等号去掉并为table导入键值
结果 = {[a]=3,["不作死"]="就不会死",["你要怎么"]="列表"}
遇到不能一次分开的可以进行多次分割,若是动态文本则最好先转一个固定的格式。基本上处理字符串先是要格式比较好,后续处理才比较简单。至于-*+这三个的区别用处得多熟练,因为这三个很相似,所以很容易搞乱= =实在弄不清楚开SCITE去试试╮(╯▽╰)╭
愉快的一天又过去了╮(╯▽╰)╭
什么!居然写了一天!?o(>﹏<)o
我的小结:
match找到的内容,find找到的结果,sub子串
函数名前有g表示全局,即对整个字符串处理,分割字符串可以用string.gsub。
(转)LUA正则表达式不完全指南的更多相关文章
- lua游戏开发实践指南学习笔记1
本文是依据lua游戏开发实践指南做的一些学习笔记,仅用于继续自己学习的一些知识. Lua基础 1. 语言定义: 在lua语言中,标识符有非常大的灵活性(变量和函数名),只是用户不呢个以数字作为起始符 ...
- [Lua游戏AI开发指南] 笔记零 - 框架搭建
一.图书详情 <Lua游戏AI开发指南>,原作名: Learning Game AI Programming with Lua. 豆瓣:https://book.douban.com/su ...
- [转]Lua和Lua JIT及优化指南
一.什么是lua&luaJit lua(www.lua.org)其实就是为了嵌入其它应用程序而开发的一个脚本语言, luajit(www.luajit.org)是lua的一个Just-In-T ...
- 读Lua游戏开发实践指南
11月11日开读,到今天正好一个月. 起因是被裁员之后,发现很多公司都在使用lua编写cocos2d-x游戏,原因是上手快,技术人员比较便宜. 如果引擎封装比较好,几乎在lua里写写基本逻辑就行了,不 ...
- 《Lua游戏开发实践指南》读后感
书籍地址:http://book.douban.com/subject/20392269/ 一句话点评该书:想用Lua作游戏脚本开发的同学值得一读! (一)本书特点 市面专门讲Lua的中文书籍非常少, ...
- Openresty 学习笔记(二)Nginx Lua 正则表达式相关API
ngx.re.match 语法: captures, err = ngx.re.match(subject, regex, options?, ctx?, res_table?) 环境: init_w ...
- Lua脚本性能优化指南
https://github.com/flily/lua-performance/blob/master/Guide.zh.md https://springrts.com/wiki/Lua_Perf ...
- lua正则表达式如何匹配中文
function CheckChinese(s) local ret = {}; local f = '[%z\1-\127\194-\244][\128-\191]*'; local line, l ...
- lua正则表达式替换字符串
local _t = {} _t.name = "Li" local str = string.gsub("hahah---[name]----[age]--xrz-&q ...
随机推荐
- OTL调用存储过程/函数及注意事项
OTL 是 Oracle, Odbc and DB2-CLI Template Library 的缩写,是一个 C++ 编译中操控关系数据库的模板库,它目前几乎支持所有的当前各种主流数据库. OTL ...
- django queryset合并问题
今天在实现搜索时遇到一个问题,如何同时搜索model里面的title以及content和category字典 contents = Blog.objects.filter(content__conta ...
- echarts图形报表缓存问题(option数据缓存)
这几天我在工作中用到了echarts开发报表.每次查询出来的数据都是新的,但是echart展现的图形报表却还是之前的数据.网上找了搜索了很多次也没能解决,后面加了技术群才解决的. 我开始已经确定是报表 ...
- apache2.4 的安装
Apache2.4 安装包下载地址 http://httpd.apache.org/docs/current/platform/windows.html#down 选择ApacheHaus 进入后 这 ...
- Index 和 Type 的区别
原文: Index vs. Type By Adrien Grand 译者: fengchang 对于 ES 的新用户来说,有一个常见的问题:要存储一批新的数据时,应该在已有 index 里新建一个 ...
- Hadoop 伪分布式上安装 HBase
hbase下载:点此链接 (P.S.下载带bin的) 下载文件放入虚拟机文件夹,打开,放在自己指定的文件夹 -src.tar.gz -C /home/software/ 修改环境配置 gedit / ...
- HttpServletRequest和HttpServletResponse详解
请求与响应相关的类和接口非常多,下表是主要的与请求和接口相关的类以及接口. 主要的与请求和接口相关的类及接口 方 法 说 明 ServletInputStream Servlet的输入流 ...
- JAVA简单选择排序算法原理及实现
简单选择排序:(选出最小值,放在第一位,然后第一位向后推移,如此循环)第一位与后面每一个逐个比较,每次都使最小的置顶,第一位向后推进(即刚选定的第一位是最小值,不再参与比较,比较次数减1) 复杂度: ...
- 帮助快速生成页面固定显示元素的jQuery插件 - sticky-kit
来源:GBin1.com 如果需要在用户滚动页面的时候,保持特定元素始终可见的话,今天这里我们介绍的Sticky-Kit是一个不错的选择. 它是一个开源的jQuery插件,可以帮助大家快速针对页面元素 ...
- Hibernate从入门到上手(纯java project、Maven版本hibernate)
Hibernate(orm框架)(开放源代码的对象关系映射框架) Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一 ...