zoukankan      html  css  js  c++  java
  • Chapter 21_3 模式

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

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

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

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

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

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

    %.    表示匹配一个"."

    %% 表示匹配一个“%”

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

    . 所有字符
    %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(2,string.gsub(text , "[AEIOUaeiou]",""))

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

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

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

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

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

    "[^ ]"表示除了换行符以外的其他字符。但是对于简单的分类,可以使用大写形式得到其补集,"%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参考手册

  • 相关阅读:
    swift mac 使用git, 并使用osc, 打开当前目录命令在终端输入 open . windows 下为start .
    压力测试-jmeter
    nginx在线与离线安装
    数据库架构简要解析
    maven-build-downloading
    springboot-权限控制shiro(二)
    mysql8报错解析
    springboot-权限控制shiro(一)
    pycharm问题解析(connecting to console)
    springboot-热部署Jrebel
  • 原文地址:https://www.cnblogs.com/daiker/p/5900350.html
Copyright © 2011-2022 走看看