Lua字符串及模式匹配

摘要:
字符类基础函数举例介绍:string.lenstring.lowerstring.upperstring.rep==˃aaaaastring.substring.substring.sub函数会提取子串by子串所在字符串的位置下标string.char()string.byte()string.format模式匹配函数举例介绍:字符串=˃被查找的字符串子串=˃要查找的字符(串)string.find返回子串的前后位置string.find返回相同位置string.find该函数的第三个参数是开始查找下标由此,find函数简单查找子串返回值是2个值;没有找到,即返回nil。string.gsub_G是全局变量的table函数:gsub每次找到匹配字符串时,调用该函数并将匹配字符串作为参数传入。

字符类基础函数举例介绍:

  string.len( ‘string’ )  
  string.lower( ‘string’ )
  string.upper( ‘string’ )
  string.rep( ‘a’ , 5 )  ==> aaaaa
  string.sub( ‘string’ , I , j )
  string.sub( s, string.find(s, 'world') )
  string.sub函数会提取子串by子串所在字符串的位置下标
  string.char()   string.byte()
  string.format( ‘%02d:%02d:%02d’ , d , m , y )

模式匹配(pattern-matching)函数举例介绍:

字符串=>被查找的字符串
子串=>要查找的字符(串)

  string.find( 'string', 'substr' )  返回 子串的前后位置
  string.find( 'string', 'c' )  返回相同位置
  string.find( s, 'substr', index ) 该函数的第三个参数是开始查找下标

由此,find函数简单查找子串(包含字符) 返回值是2个值;没有找到,即返回nil。

  string.match()函数返回匹配到的子串的一份copy。
  string.match( 'string' , '%d+/%d+%d+') -->12/23/34

  string.gsub( 'Lua is cute', 'cute', 'great' )  -->Lua is great

用第三个参数替换第一个参数中所有出现的第二个参数,并返回整串以及发生的实际替换次数。

  string.gsub( 'all lla' , 'l' , 'x' , 3 ) -->axx xla 第四个参数限制替换的次数

  string.gmatch(s, '%a') 将返回一个函数,遍历到所有的模式指定子串by返回的函数。
  words = {}
  for w in string.gmatch( s, "%a+" ) do
     words[#words+1] = w
  end

总结一下:各模式匹配函数的基本简单功能

  `find( 'string' , 'strsub' , index )`   从起始位置(index)查找子串返回位置
  `match( 'string' , '%s%d.....' )`  匹配捕获,返回子串的copy
  `gmatch( 'string', '%s%d' )`  全局匹配捕获,返回一个函数提供所有子串
  `gsub( 'string' , 'go' , 'come' , count)`  替换字符串中所有go子串换count次

其实,差不多是根据函数返回值不同,则大约功能相差,参数排布相似,并且都是遍历查找功能。那么上面大致的三类就涵盖了模式匹配3个大的功能方面:查找,捕获,替换。


模式们(基础元素)

模式就是一种字符串,模式函数会解释它们,它们就有了意义
字符分类:(字符,即一个)分类字符们的大写表示相对补集

  %d(数字)        %a(字母)      %c(控制字符)    %l(小写字母)
  %p(标点)        %s(空白字符)                    %u(大写字母)
  %w( a | d )       %x(十六进制数字)
  特殊字符们: (  )  .  %  +  -  *  ?  [  ]  ^  $
  普通字符串,用来转义: ‘
’

模式函数解释模式串: 模式中的 特殊字符们需要使用原字符意义用%转义。

但是,尝试了一下这种情况:string.find( s , ‘^[+-]?%d+$’ )
依然能够匹配出字符串前面的+-号,当然string.find( s,‘[%+%-]?%d+’)
也能够匹配出结果。所以,建议使用后者,含义比较清晰。

  字符集: [%w_]  [AEIOUaeiou]  [0-9A-Fa-f]  [^
]  [^%s] %S
  描述模式的重复和可选:  

   +  重复1次以上 
   *-  重复随便几次
   ?  0次,1次

捕获 “( )”

函数string.match会将所有捕获到的值返回

  date = “Today is 12/12/2012”
  d , m , y = string.match( date, “(%d+)/(%d+)/(%d+)”)
  %d 用来匹配与前面第d个捕获相同内容,不仅是字符个数相同。
  q,quotedPart = string.match( s , “([”’])(.-)%1”)  %1的地方必须要与前面([”’])相同的内容来填补%1此位置。

  s = string.gsub(s , “\(%a+){(.-)}” , “<%1><%2><\%1>” )

%d此占位捕获前面位置内容的项,也可以用在替换函数中。

   function  trim ( s )
    return ( string.gsub( s , “^%s*(.-)%s*$” , “%1” ) )
   end

替换

string.gsub函数的第三个参数不仅是替换的字符串,还可以是一个table , 或者是一个函数。
table: gsub每次找到匹配字符串时,以此字符串作为key,用table中对应的value来替换,没有对应value,不替换。
string.gsub( s , “$(%w+)” , _G )_G是全局变量的table

函数:gsub每次找到匹配字符串时,调用该函数并将匹配字符串作为参数传入。

  string.gsub( s , “$(%w+)” , function(n)
     return tostring( _G[n] )
  end )

举例

将login_string长字符串中内容读取到一个table中,去除前面无意义前缀

   login_string = "lgn|Puserid=4542379,svrid=qxzh0001,fcm=0,timestamp=1381311260,idc=U,origin=,c=0,sign=0d0cc04dd64b4c2e2d9d8102834b45d6"
   --长字符串中前5个字符去掉
   kvtable = { }

   login_string_std = string.sub(login_string , 6)  -- lua中索引从1开始
  
   --因为长字符串中有字段的内容为空'origin',模式中第二个选用*
   for k,v in string.gmatch(login_string_std , "(%a+)=(%w*)") do
        kvtable[k] = v
   end

补充:pairs 与 ipairs

在遍历table的时候的区别:
首先,说明一下,数组table(array)就是 key 为连续数字的table.
那么,简而言之,ipairs是遍历数组的;pairs是遍历记录table(k,v)的

pairs来遍历table(k,v),将会逐个读取出来,而遍历table(array)也会全部读取出来。
ipairs来遍历table(k,v),将会停止在第一个非数字key的地方或者停止在得到的value是nil的地方,而遍历table(array)就顺利全部遍历出来了,返回0。
最后,使用ipairs比较严格,使用pairs比较宽松。

免责声明:文章转载自《Lua字符串及模式匹配》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇boost正则库匹配ASII编码的中文、全角字符示例SAP快捷方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

layui实现分页

 一 准备工作 首先必须先引入layui的完整目录,也就是你下载下来的整个layui的目录都要放在你的资源文件夹下,也就是这个文件目录 刚开始接触layui的时候,以为和jquery,vue等框架一样,只需要引入相应的js文件和css文件,模快便可以直接使用,因此走了不少的弯路,layui是分模块化的,只有在使用的时候,layui会去modules下找你u...

SpringBoot+Mybatis-Plus两种分页方法

用到的依赖: <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatisplus.version}&l...

springboot多环境下的自定义配置文件,并读取到常量

import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Com...

hive基础1

Hive基础 1、介绍 Hive是OLAP(online analyze process,在线分析处理)。通常称为数据仓库,简称数仓。内置很多分析函数,可进行海量数据的在线分析处理。hive构建在hadoop之上,使用hdfs作为进行存储,计算过程采用的是Mapreduce完成,本质上hive是对hadoop的mr的封装,通过原始的mr方式进行数据处理与分...

java--枚举

前言   java中enum其实也是一种class类型,他和一般的class不同的是    1.全局只有一个实例    2.不能拥有public构造函数    3.无法继承和被继承 枚举案例 public enum HttpCode { SUCCESS(200, "操作成功"),//每定义一个枚举项,就相当通过构造函数HttpCode(int co...

TCP/IP网络编程系列之三(初级)

TCP/IP网络编程系列之三-地址族与数据序列 分配给套接字的IP地址和端口 IP是Internet Protocol (网络协议)的简写,是为首发网络数据而分配给计算机的值。端口号并非赋予计算机值,而是为了区分程序中创建的套接字而分配给套接字的序号。 网络地址 网络地址分为IPV4和IPV6,分别你别为4个字节地址簇和6个字节地址簇。IPV4标准的4个字...