转自剑侠论坛,并稍微修改个别文字。

好不容易闲下来,研究了一下正则表达式,然后越钻越深,经过跟大神们讨论学习后,就没有然后了。总之╮(╯▽╰)╭很有用的一个东西,至少对于用户输入的读取方面会比较方便,所以就简单举例说说。

注:正则这个比较不好理解,经常容易转不过弯来,个人觉得最好的学习方式就是自己去试,举一反三,才会知道错在哪里,我尽量提供不同种类同样用法的例子方便理解。

正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。(好吧,这是百度来的)
简单来说就是按照一定想法获取与替换字符串。想怎么换就怎么换(真的( ⊙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正则表达式不完全指南的更多相关文章

  1. lua游戏开发实践指南学习笔记1

    本文是依据lua游戏开发实践指南做的一些学习笔记,仅用于继续自己学习的一些知识. Lua基础 1.  语言定义: 在lua语言中,标识符有非常大的灵活性(变量和函数名),只是用户不呢个以数字作为起始符 ...

  2. [Lua游戏AI开发指南] 笔记零 - 框架搭建

    一.图书详情 <Lua游戏AI开发指南>,原作名: Learning Game AI Programming with Lua. 豆瓣:https://book.douban.com/su ...

  3. [转]Lua和Lua JIT及优化指南

    一.什么是lua&luaJit lua(www.lua.org)其实就是为了嵌入其它应用程序而开发的一个脚本语言, luajit(www.luajit.org)是lua的一个Just-In-T ...

  4. 读Lua游戏开发实践指南

    11月11日开读,到今天正好一个月. 起因是被裁员之后,发现很多公司都在使用lua编写cocos2d-x游戏,原因是上手快,技术人员比较便宜. 如果引擎封装比较好,几乎在lua里写写基本逻辑就行了,不 ...

  5. 《Lua游戏开发实践指南》读后感

    书籍地址:http://book.douban.com/subject/20392269/ 一句话点评该书:想用Lua作游戏脚本开发的同学值得一读! (一)本书特点 市面专门讲Lua的中文书籍非常少, ...

  6. Openresty 学习笔记(二)Nginx Lua 正则表达式相关API

    ngx.re.match 语法: captures, err = ngx.re.match(subject, regex, options?, ctx?, res_table?) 环境: init_w ...

  7. Lua脚本性能优化指南

    https://github.com/flily/lua-performance/blob/master/Guide.zh.md https://springrts.com/wiki/Lua_Perf ...

  8. lua正则表达式如何匹配中文

    function CheckChinese(s) local ret = {}; local f = '[%z\1-\127\194-\244][\128-\191]*'; local line, l ...

  9. lua正则表达式替换字符串

    local _t = {} _t.name = "Li" local str = string.gsub("hahah---[name]----[age]--xrz-&q ...

随机推荐

  1. 如何打造一款可靠的WAF

    之前写了一篇<WAF防御能力评测及工具>,是站在安全运维人员选型WAF产品的角度来考虑的(优先从测试角度考虑是前职业病,毕竟当过3年游戏测试?!).本篇文章从WAF产品研发的角度来YY如何 ...

  2. 关于C#中async/await中的异常处理(上)

    关于C#中async/await中的异常处理(上) 2012-04-11 09:15 by 老赵, 17919 visits 在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕 ...

  3. 报错:maven:java.lang.NoClassDefFoundError: org/apache/commons/io/Charsets

    运行报错: maven:java.lang.NoClassDefFoundError: org/apache/commons/io/Charsets 找不到Charsets这个类 上网查了以后,是因为 ...

  4. MapReduce报错:Error: java.io.IOException: Initialization of all the collectors failed. Error in last collector was :interface javax.xml.soap.Text

    这个问题折腾了我一天了,最主要的是真的不懂在哪里看log,所以虽然折腾地很没有道理但还是一直在折腾. 这个问题很好解决,在main函数处错误import了 javax.xml.soap.Text,应该 ...

  5. NHibernate中几个集合的选择

    NHibernate是从Hibernate移植过来的基于NET平台的一个ORM框架,同时跟这框架一起的还有一个开源库,叫做Iesi.Collections,这个库扩展了NET平台下面的几个集合,所谓集 ...

  6. [ES6] 08. Destructuring Assignment -- 1

    Here is the way you get value from an object: var obj = { color: "blue" } console.log(obj. ...

  7. java泛型介绍

    一.泛型初衷 Java集合不会知道我们需要用它来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要就具有很好的通用性.但这样做也带来两个问题: –集合对元素类型没有任何限制,这样可能引 ...

  8. [iOS开发] 使用Jenkins自动打包并上传至蒲公英

    设置构建触发器 Poll SCM H/2 * * * * 设置 构建脚本 # #xodebuild & jenkins 自动构建并上传至pgyer.com #2017年5月9日 # #定义一些 ...

  9. 原来这是一个经典面试题-------Day61

    前几天在table的操作中,记录了动态生成表格的三种方式: 1.html语言的拼接:用字符串或者数组拼接在html语言中,这个理解起来最直观 2.插入行和列:insertRow()和insertCel ...

  10. Android NDK学习记录(一)

    一.NDK环境在Mac中部署 1.准备eclipse,android sdk安装包,android ndk安装包(http://dl.google.com/android/ndk/android-nd ...