(转)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 ...
随机推荐
- gmock学习01---Linux配置gmock
本文目的 本文主要介绍gmock 1.6.0版本在Linux上如何部署和使用. gmock是做什么的? 使用C++手动编写mock对象将会是一件十分耗时,易于出错,枯燥乏味的事情.gmock提供一整套 ...
- zabbix3.2 报错 Database error
一.Database errorThe frontend does not match Zabbix database. Current database version (mandatory/opt ...
- unity macro 分平台处理
https://docs.unity3d.com/ScriptReference/SystemInfo.html https://docs.unity3d.com/Manual/PlatformDep ...
- MFC【17-1】线程和线程同步化
17.1线程 对于Windows来说所有的线程都是一样的,但MFC却把线程区分为两种类型:User Interface(UI) threads(用户界面(UI)线程)和Worker threads(工 ...
- Hibernate异常:Unable to locate appropriate constructor on class
异常信息:org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class o ...
- Fedora 中的容器技术:systemd-nspawn
本文将说明你可以怎样使用 Fedora 中各种可用的容器技术和学习“systemd-nspawn”的相关知识. 容器是什么? 一个容器就是一个用户空间实例,它能够在与托管容器的系统(叫做宿主系统)相隔 ...
- zookeeper伪分布式集群安装
1.安装3个zookeeper 1.1创建集群安装的目录 1.2配置一个完整的服务 这里不做详细说明,参考我之前写的 zookeeper单节点安装 进行配置即可,此处直接复制之前单节点到集群目录 创建 ...
- ubuntu14.04使用root用户登录桌面,ubuntu14.04root 转
ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...
- 5种样式实现div容器中三图摆放实例对比说明
代码地址如下:http://www.demodashi.com/demo/11593.html 效果演示: demo点查看效果 需求说明: 如下图所示为设计图,希望在图片上传无规则无规律的情况下实现设 ...
- 效仿盖茨:PPstream创始人的心路历程
http://www.jianglb.com/2007/08/15/about-ppstream.html “P2P网络视频软件的目标是成为网民肚子里的蛔虫.”PPstream总裁徐伟峰自信地说道.他 ...