Lua string patterns

匹配夏日模式.png

前言#

今天是我每天一篇技术总结计划的第60天,也就是说我坚持每天一篇技术总结已经整整两个月了,我先给自己点个赞。今天也正好是lua函数中string家族里讲解完结的一章,在这一段时间中我们经常会在章节中听到模式匹配这个词,这也是string库函数的强大之处。

Lua并不使用POSIX规范的正则表达式来进行模式匹配。主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大。权衡之下,Lua中的模式匹配的实现只用了500行代码,当然这意味着不可能实现POSIX所规范的所有功能。但是Lua中的模式匹配功能也是很强大的,并且包含了一些使用标准POSIX模式匹配不容易实现的功能。

前面几章一直跟大家说会总结一下模式匹配这一块的内容,今天是周末我就利用多一点时间,根据lua官方文档中关于模式的介绍为主线,我们一起来总结一下lua中关于模式匹配的内容,其中大部分内容官方文档已经介绍过了,我就是翻译一下,可能有理解不正确的地方,欢迎大家批评指正。

内容#


string patterns##


1.Character Class
一个字符类可以被用于表示一组字符,以下组合被允许来来描述一个字符类:

  • x :表示字符x本身(这里的x表示不是魔法字符^$()%.[]*+-?中的一个)。
  • . :表示所有字符(一个点/英文中句号)。
  • %a:表示所有字母。
  • %c:表示所有控制字符。
  • %d:表示所有十进制数字。
  • %l:表示所有小写字母。
  • %p:表示所有标点符号。
  • %s:表示所有空白字符。
  • %u:表示所有大写字母。
  • %w:表示所有字母和数字。
  • %x:表示所有十六进制数。
  • %z:表示0值字符。
  • %x:表示字符x(此处的字符x不是字母或数字)。这是讲魔术字符转义的标准方式,当被用于在模式中表示自身时,任何标点符号(甚至非魔术的)都能加一个前缀%
  • [set]:表示set中的所有字符的联合构成的分类。通过用-分隔截止字符可以指定某个范围的字符。上面描述的所有种类的%x都可用作set的组成部分。set中的所有其他字符表示它们自身。例如[%w_](或[_%w])表示所有字母数字字符和下划线,[0-7]表示八进制数字,[0-7%l%-]表示八进制数字和小写字母以及-字符。
  • [^set]:表示set的补集,其中的set在上面解释了。
  • 字符范围和字符类之间的相互作用是未定义的。因此类似[%a-z]或[a-%%]的模式没有意义。
  • 对于所有单字母表示的字符类(%a%c等等),相应的大写字母表示该字符类的补集。例如,%S表示所有非空白符。
  • 字母、空白和其他字符组合的定义依赖于当前locale。特别地,字符类[a-z]可能不等于%l。

2.Pattern Item
一个模式选项可以是:

  • 一个单个字符类,它匹配该类中的任意单个字符。
  • 一个后跟*的单个字符类,它匹配该类中的0或多个字符。这些重复项将总是匹配最长的可能序列。
  • 一个后跟+的单个字符类,它匹配该类中的1或多个字符。这些重复项将总是匹配最长的可能序列。
  • 一个后跟-的单个字符类,它也匹配该类中的0或多个字符。与*不同,这些重复项将总是匹配最短的可能序列。
  • 一个后跟?的单个字符类,它匹配出现0或1次该类中的字符。
  • %n中的n在1和9之间,这种项匹配一个等价于捕获的字符串的第n个子串(见下面)
  • %bxy中x和y是两个不同的字符;这种项匹配始于x终于y的字符串,并且xy是对称的。这表示,如果一个人从左到右读字符串,对x计数为+1,对y计数为-1,结尾的y是第一个遇到计数为0的y。例如,项%b()匹配带有平衡的圆括号的表达式。

3.Pattern

模式是一系列的模式项。在模式开头的^将匹配固定在源串的开头。在模式结尾的$将匹配固定在源串的结尾。在其他位置上,^$没有特殊含义,表示它们自身。


4.Captures

模式可以含有括在圆括号内的子模式,它们描述捕获。当成功进行一个匹配,源串中匹配捕获的子串被存储(捕获)以便将来使用。捕获根据它们的左圆括号进行编号。例如,在模式"(a*(.)%w(%s*))"中,字符串的匹配"a*(.)%w(%s*)"的部分作为第一个捕获被存储(因此被编号为1),匹配"."的字符被捕获并编号为2,匹配"%s*"的部分被编号为3。

作为一种特殊情况,空捕获()捕获当前字符串位置(一个数字)。例如,如果我们把模式()aa()用于字符串"flaaap",将有两个捕获:3和5。

模式不能含有内嵌的0(即'\0')。使用%z代替。


usage##

  • 首先我们新建一个文件将文件命名为patterntest.lua然后编写代码如下:
-- 这是一个原串
local sourcestr = "ehrt999wj=--=-*-/4mdqwl\0ds123tfef"
print("\nsourcestr = "..string.format("%q",sourcestr));

-- '%z'的使用
local match_ret = string.match(sourcestr, "%z")
print("\n%z match_ret is ", string.format("%q",match_ret))

-- '*'的使用
match_ret = string.match(sourcestr, "%a*")
print("\n%a* match_ret is ", string.format("%q",match_ret))

-- '-'的使用(其实我有点迷糊)
match_ret = string.match(sourcestr, "%a%d-")
print("\n%a- match_ret is ", string.format("%q",match_ret))

-- '%bxy'的使用
match_ret = string.match(sourcestr, "%bhs")
print("\n%bhs match_ret is ", string.format("%q",match_ret))

-- '()xxx()'的使用
local match_ret1, match_ret2 = string.match(sourcestr, "()t9()")
print("\n()t9() match_ret is ", string.format("%q",match_ret1), 
    string.format("%q",match_ret2))
  • 运行结果
string_pattern.png

总结#

  • 为了测试其中一些字符类的效果,我们使用了函数string.match()这个相对简单的函数,可以说明问题就行了。
  • 在代码中我们举了几个不太好理解的例子,比如%z%bxy%a*等,大家可以看一下输出结果感受一下。
  • 在例子中特别是最后一个不太好理解,我的理解是第一个括号输出的索引是捕获字符串的第一个位置,后一个括号输出的是捕获字符串结束的后一个位置。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • string库提供了字符串处理的通用函数。 例如字符串查找、子串、模式匹配等。 当在 Lua 中对字符串做索引时,...
    chiguozi阅读 3,727评论 0 3
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,151评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 《老黄县》里记载这么一句话,黄县三村大:北马、中村、洼。北马集,地盘大,且由来已久,热闹繁盛。尤其是腊月二十八,北...
    你若安好便是晴天qah阅读 1,421评论 6 4
  • 2017.2.25写作第21天 今天是21天写作训练营最后一天。特别荣幸自己坚持下来了。 其实人生有很多事都是因为...
    80后女诸葛阅读 289评论 1 1