lua正则匹配中文_Lua的字符串匹配与正则表达式

本文详细介绍了Lua中的字符串匹配函数find、match、gmatch和gsub的使用,以及Lua支持的正则表达式,包括元字符、字符集、重复、分组等,并通过实例演示了各种用法。
摘要由CSDN通过智能技术生成

Lua的字符串匹配与正则表达式

使用lua一段时间了,简单总结下string库中的几个与正则相关的函数。这些函数是find,match, gmatch和gsub。然后是lua中支持的正则。文中的例子在lua5.3的命令行中试验过。5.1版的需要在提示符前加一个=号或加return空格。

string.find(s, pattern[, init[, plain]])

在字符串s中匹配pattern,如果匹配成功返回第一个匹配到的子串的起始索引和结束索引,如果pattern中有分组,分组匹配的内容也会接着两个索引值之后返回。如果匹配失败返回nil。

可选数值参数init表示从s中的哪个索引位置开始匹配,缺省值是1,可以为负索引。

可选布尔值参数plain为true时,pattern作为普通字符串匹配,所有正则中的元字符都只被作为普通字符解析。(这个参数并不是匹配字符串的结束索引)

#########

string.find('Hanazawa Kana', 'na')

34

string.find('Hanazawa Kana', '[%a]+')

18

string.find('2015-5-12 13:53', '(%d+)-(%d+)-(%d+)')

192015512

string.find('2015-5-12 13:53', '(%d+)-(%d+)-(%d+)', 1, true)

nil

string.find('%a1234567890%a', '%a', 3, true)

1314

string.match(s, pattern[, init])

在字符串s中匹配pattern,如果匹配失败返回nil。否则,当pattern中没有分组时,返回第一个匹配到的子串;当pattern中有分组时,返回第一个匹配到子串的分组,多个分组就返回多个。可选参数init表示匹配字符串的起始索引,缺省为1,可以为负索引。

> string.match('2015-5-12 13:53', '%d+-%d+-%d+')

2015-5-12

> string.match('2015-5-12 13:53', '(%d+)-(%d+)-(%d+)')

2015512

> string.match('2015-5-12 13:53', '((%d+)-(%d+)-(%d+))')

2015-5-122015512

可以发现,所有用到match的地方都可以用find来实现。match是find的一个简化版

string.gmatch(s, pattern)

返回一个迭代器。每当迭代器调用时,返回下一个匹配到的子串,如果pattern中有分组,返回的是子串对应的分组。gmatch也可以用find和循环来实现。

> for s in string.gmatch('2015-5-12 22:20', '%d+') do print(s) end

2015

5

12

22

20

> for s in string.gmatch('Hanazawa Kana', 'a(%a)a') do print(s) end --找出形如“a字母a”中间的字母

n

w

n

> for k, v in string.gmatch('a=214,b=233', '(%w+)=(%w+)') do print(k, v) end

a214

b233

看上面第二个测试例子,处于两个a字母中间的单个字母还有‘z’,但循环并没有输出。原因是在'ana'匹配成功之后,接下来匹配是从'z'开始的,z没有被匹配到。正确的模式pattern应该不要捕获'a(%a)a'的后面的a,用python的正则可以写成'a(\w)(?=a)',他不会消耗掉后面的a。但是lua不支持(?=...)。(python中\w表示单词字符[a-zA-Z0-9_],记不清就把这类元字符列出来 如 %a写成[a-zA-Z] 。)

string.gsub(s, pattern, repl[, n])

替换字符串函数!这个功能应该是字符串处理中实用性最强的一个。

把字符串中用模式pattern匹配到的所有子串替换为repl指代的子串,返回替换后的字符串和替换的次数。可选数值参数n表示最多可替换的次数。

参数repl可以是正则表达式,也可以是函数。当repl是函数时,函数的参数是模式pattern捕获的子串,和match类似,有分组返回分组,无分组返回整个子串。函数最后应该返回一个字符串。如果repl是正则表达式,可以用分组序号引用匹配到的分组。

> string.gsub('Hanazawa Kana', 'na', 'nya')

Hanyazawa Kanya

> string.gsub('Hanazawa Kana', 'na', function(s) return string.sub(s,1,1)..'y'..string.sub(s,2,2) end)

Hanyazawa Kanya

> string.gsub('Hanazawa Kana', '(n)(a)', function(a,b) return a..'y'..b end)

Hanyazawa Kanya

> string.gsub('Hanazawa Kana', '(n)(a)', '%1y%2')

Hanyazawa Kanya

Lua中的正则表达式

正则表达式由元字符按照规则(语法)组成。lua中的特殊字符是%.^$+-*?,一共12个。它们和一般字符按规则构成了lua的正则表达式。

元字符描述表达式实例完整匹配的字串

字符

普通字符除去%.[]()^$*+-?的字符,匹配字符本身KanaKana

.匹配任意字符Ka.aKana

%转义字符,改变后一个字符的原有意思。当后面的接的是特殊字符时,将还原特殊字符的原意。%和一些特定的字母组合构成了lua的预定义字符集。%和数字1~9组合表示之前捕获的分组K%wna

%%na%%

(a)n%1Kana

%na%

ana

[...]字符集(字符类)。匹配一个包含于集合内的字符。[...]中的特殊字符将还原其原意,但有下面几种特殊情况

1. %],%-,%^作为整体表示字符']','-','^'

2. 预定义字符集作为一个整体表示对应字符集

3. 当]位于序列的第一个字符时只表示字符']'

4. 形如[^...],[...-...]有特定的其他含义[a%]na

[%a]na

[%%a]na

[]]na

[%]]na

[a-]na%na

wna

wna

]na

]na

-na

[...-...]-表示ascii码在它前一个字符到它后一个字符之间的所有字符[a-z]ana

[^...]不在...中的字符集合。[^0-9]na

[^^0-9]naKna

Kna

重复(数量词)

*表示前一个字符出现0次或多次[0-9]*

[a-z]*9*2009

na

+表示前一个字符出现1次或1次以上n+[0-9]+n2009

?表示前一个字符出现0次或1次n?[0-9]+2009

预定义字符集

%s空白符[ \r\n\t\v\f]an[%s]?9an 9

%p标点符号an[%p]9an.9

%c控制字符

%w字母数字[a-zA-Z0-9][%w]+Kana9

%a字母[a-zA-Z][%a]*Kana

%l小写字母[a-z]-

%u大写字母[A-Z]-

%d数字[0-9]-

%x16进制数[0-9a-fA-F]-

%zascii码是0的字符-

分组

(...)表达式中用小括号包围的子字符串为一个分组,分组从左到右(以左括号的位置),组序号从1开始递增。ab(%d+)

(%d+)%1ab233

123123

边界匹配(属于零宽断言)

^匹配字符串开头^(%a)%w*abc123

$匹配字符串结尾%w*(%d)$abc123

%b

%bxy平衡匹配(匹配xy对)。这里的x,y可以是任何字符,即使是特殊字符也是原来的含义,匹配到的子串以x开始,以y结束,并且如果从x开始,每遇到x,计算+1,遇到y计数-1,则结束的y是第一个y使得计数等于0。就是匹配成对的符号,常见的如%b()匹配成对的括号%b()

%d+%b()(3+4(x*2))

2(3+4(x*2))

**备注**

1. lua不支持分组后面接重复词(+*?),对于复杂的匹配可以用find+循环手动处理。

2. %bxy跟预定义字符集有区别,前者在[...]仍保持原意,后者则失去特殊意义

3. 上表中是lua对正则的支持,其他的正则如命名组,重复{m, n}等并不能在lua中用。注意转义字符是%不是\

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值