很多地方都会看到各种匹配模式,每次接触这些函数,颇使人望文生畏。

  今天就来好好面对它、认识它、了解它、最后战胜它。

  匹配模式都是用一串常规的字符串来描述,最主要的是理解这些字符串的语法及含义(即它能匹配到什么)。

^$()%.[]*+-?

魔法字符,具有特殊的含义。

%作为这些魔法字符的转义字符,还可以用于其他所有非字母和数字。

%.    表示匹配一个"."

%% 表示匹配一个“%”

当不确定一个字符是否需要转义时,应该前置一个转义符。

. 所有字符
%a 字母
%c 控制字符
%d 数字
%g 除空白符外的可打印字符
%l 小写字母
%p 标点符号
%s 空格字符
%u 大写字母
%w 字母及数字
%x 16进制数字符号
%x

表示字符x(这里的x是任意非字母或数字的字符),这是对魔法字符转义的标准方法。

所有非字母或数字的字符(标点,非魔法字符) 都可以用前置一个"%"放在模式串中表示自身。

[set]

表示set中所有字符的联合。可以以‘-’连接升序书写范围两端的字符,来表示一个范围的字符集。

上一个%x形式也可以在set中使用表示其中的一个元素。其它出现在set中的字符则代表它们自己。

例如:

[%w_](或[_%w]) 表示所有的字母数字加下划线

[0-7] 表示8进制数字

[0-7%l%-] 表示8进制数字、 小写字母、‘-’ 字符。

交叉使用类和范围的行为未定义。因此,像[%a-z] 或 [a-%%] 这样的模式串没有意义。

[^set] 表示set的补集

所有单个字母表示的类别(%a,%c,等),若将其字母改为大写,均表示对应的补集。

例如:%S表示所有非空格的字符。

%A表示所有非字母字符:

print(string.gsub("hello, up-down!", "%A" , "."))
--> hello..up.down. 4 -- 4 是gsub返回的第二个结果

  对于Lua来说,模式就是普通的字符串,只有模式函数才会解释它们,此时才会将'%'当作转义符来处理。

在模式中放入一个引号的方法,与在普通字符串中放入引号的方法相同,需要用"\"来对引号进行转义。

  在一对方括号"[ ]"内将不同的字符分类或单个字符组合起来,即可创建出自己的字母,数字和下划线:

"[01]" :表示匹配二进制数字

"[%[%]]":表示匹配方括号本身

  若要统计一段文本中元音的数量,可这么写:

nvow = select(,string.gsub(text , "[AEIOUaeiou]",""))

  有的时候,需要写出一段字符范围:

"[0-9]"  即为 "%d"

"[0-9a-fA-F]"  即为 "%x"

"[0-7]" 即为查找一个八进制数字,就要比"[01234567]"好

  在一个字符集前加"^",可以得到这个字符集的补集,像"[^0-7]"就表示所有非八进制数字的字符。

"[^\n]"表示除了换行符以外的其他字符。但是对于简单的分类,可以使用大写形式得到其补集,"%S"显然比"[^%s]"简单。

但是,像"[a-z]" 可能并不等于"%l"。在某些区域设置中,后者可能会包括像"á"、"ú" 、"ü"等。

  可以通过修饰符来描述模式中的重复部分和可选部分。Lua的模式提供4中修饰符:

* 0或多个,匹配尽可能长的串
+ 1或多个,匹配尽可能长的串
- 0或多个,和*不同,它匹配尽可能短的串
? 可选部分,0或1次,比如:A?将匹配0或一个A,只要有可能,它会匹配一个。
% 这里的n可以从1-9;匹配一个等于n号捕获物的子串,下一节有介绍。
%bxy

这里的x和y是两个明确的字符;匹配以x开始y结束,且其中x和y保持平衡的字符串。

意思是,如果从左到右读这个字符串,对每次读到一个x就+1,读到一个y就-1,最终

结束处的那个y是第一个记数到0的y。比如:条目"%b()"可以匹配到括号平衡的表达式。

%f[set] 指边境模式;这个条目会匹配到一个位于set内某个字符之前的一个空串,

%a+举例说明:

print(string.gsub("one,and two ;and three","%a+","word"))
--> word , word word; word word

%d+举例说明:

print(string.match("the number 1298 is even","%d+"))
--> 1298

*与+的用途,一个典型是匹配一个模式不同部分之间的空格。例如,匹配像"()"或"(  )"这样的一对空圆括号。可以使用模式:

"%(%s*%)"  --0或多个空格字符

匹配标识符:

"[_%a][_%w]*"

"-"和"*"差别不大,但是有时结果却截然不同。

"[_%a][_%w]-" --查找一个标识符,只会找到第一个字母,因为"[_%w]-"总是匹配空串。
"/%*.*%*/" --查找一个C程序中的注释,".*"会尽可能地扩展,因此"/*"只会与最后一个"*/"相匹配
test = "int x;/* x */ int y; /* y */"
print(string.gsub(test,"/%*.-%*/","<COMMENT>")) --只找第一个"*/"就完成第一个注释
--> int x ; <COMMENT> int y;<COMMENT> print(string.match(test,"/%*.*%*/"))
--> /* x */ int y; /* y */ 这里的".*"尽可能找很多。所以打印了从头到尾的注释

"?"匹配一个可选的字符

"[+-]?%d+"    --在一段文本中寻找一个可选正负号的整数,像-12、23、+1009这样的数

"^"和"$"

if string.find(s,"^%d") then ...   --检查s串是否以一个数字开头
if string.find(s,"^[+-]?%d+$") then ... --检查s串是否表示一个整数,并且没有多余的前导字符和结尾字符

"%b" 匹配成对的字符

用法是"%b<x><y>"

其中<x>和<y>是两个不同的字符,<x>是起始字符,<y>是结束字符:例如 "%b()"

s = "a (enclosed(in) parentheses) line"
print(string.gsub(s,"%b()", "")) --> a line

经典用法是"%b()"、"%b[]"、"%b{}"、"%b<>",但实际上可以用任何字符作为分隔符。

"%f[%w]"  --这儿没有理解透彻

s = "the anthem is the theme"
print(s:gsub("%f[%w]","one")
--> onethe oneanthem oneis onethe onetheme print(s:gsub("%f[%w]the%f[%W]","one"))
--> one anthem is one theme

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》 和 Lua参考手册

Chapter 21_3 模式的更多相关文章

  1. Chapter 2.策略模式

    首先贴一段代码: package xiao; import java.util.Scanner; class CashSuper{    private int num;    private dou ...

  2. Chapter 13 建造者模式

    建造者模式又叫生成器模式:将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 代码: package xiao; import java.util. ...

  3. Chapter 12 外观模式

    外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个模式使得这一子系统更加容易使用. 外观模式三个阶段: 首先,在设计初期阶段,应该要有意识的将不同的两个层分离. 其次,在 ...

  4. Chapter 10 模版方法模式

    我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模版模式来处理. 模版方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模 ...

  5. Chapter 9 原型模式

    原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 简单的说就是clone一个对象实例.使得clone出来的copy和原有的对象一模一样. 插一个简单使用clone的例子,如果 ...

  6. Chapter 8 工厂方法模式

    工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行.你想要加功能,本来是改工厂类的,而现在是修改 ...

  7. Chapter 7 代理模式

    代理模式:为其它对象提供一种代理以控制对这个对象的访问. 代码: package xiao; class Girl{ private String name; public void setName( ...

  8. 《linux 内核全然剖析》 chapter 4 80x86 保护模式极其编程

    80x86 保护模式极其编程       首先我不得不说.看这章真的非常纠结...看了半天.不知道这个东西能干嘛.我感觉唯一有点用的就是对于内存映射的理解...我假设不在底层给80x86写汇编的话.我 ...

  9. <Chapter 2>2-2-1.用户偏好模式(The User Preferences Pattern)

    在这个模块中我们要创建的应用是一个简单的钟.当一个用户访问这个网站时,这个应用会更具服务器的系统时间显示当前的时间.默认情况下,这个应用使用标准国际时间(UTC)时区显示当前时间.用户可以使用Goog ...

随机推荐

  1. XMPP and SIP

    过去一年多,一直关注这方面的技术和发展,这里有一个简单的介绍,我觉得比较简洁明了.我做了一点翻译,还有我的一些评估.       SIP vs XMPP (Jabber) SIP and XMPP a ...

  2. C#伪彩色处理

    伪彩色处理是指将灰度图像转换成彩色图象.因为人眼对于彩色的分辨能力远高于对灰度图像的分辨能力,所以将灰度图像转换成彩色可以提高人眼对图像细节的辨别能力.伪彩色并不能真实的反映图像像的彩色情况. 效果图 ...

  3. Linux 宿主机安装 MiniGUI

    去MiniGUI官方网站看的时候,很兴奋,安装竟然这么容易. 上帝总是在给你一个苹果之后,赏你一巴掌.我的确是高兴太早了. 首先看一下官网文档的说明步骤: (截取于官方文档) Installing r ...

  4. Linq无聊练习系列7----Insert,delete,update,attach操作练习

    /*********************Insert,delete,update,attach操作练习**********************************/            ...

  5. 由link()和symlink()谈到软链接与硬链接

    任何一个文件可以有多个目录项指向其i节点.创建一个向现存文件连接的方法是使用l i n k函数. #include <unistd.h> int link(const char * e x ...

  6. python实现变参

    使用赋值表达式传递参数,可以颠倒参数列表的顺序.函数的参数提供默认参数 参数可以是变量,也可以是元祖.列表等内置的数据结构 在程序开发中,常常需要传递可变长度的参数.在函数的参数前使用标识符“*”可以 ...

  7. SPFA和FLOYD算法如何打印路径

    早晨碰到了一题挺裸的最短路问题需要打印路径:vijos1635 1.首先说说spfa的方法: 其实自己之前打的最多的spfa是在网格上的那种,也就是二维的 一维的需要邻接表+queue 以及对于que ...

  8. 2013.5.A

    题1 高低位交换 [问题描述] 给出一个小于2^32的正整数.这个数可以用一个32位的二进制数表示(不足32位用0补足).我们称这个二进制数的前16位为“高位”,后16位为“低位”.将它的高低位交换, ...

  9. go语言 strconv.ParseInt 的例子

    golang strconv.ParseInt 是将字符串转换为数字的函数,功能灰常之强大,看的我口水直流. func ParseInt(s string, base int, bitSize int ...

  10. [大整数乘法] java代码实现

    上一篇写的“[大整数乘法]分治算法的时间复杂度研究”,这一篇是基于上一篇思想的代码实现,以下是该文章的连接: http://www.cnblogs.com/McQueen1987/p/3348426. ...