Lua学习笔记_String(一)

Stella981
• 阅读 747

   Lua中的字符串可以包含一个字母也可以是一整本书。用一个字符串表示100K甚至1M的内容在Lua中并不罕见。  

   在Lua中,字符串是字节的序列。Lua内核中不关心这些字节是什么编码格式。Lua只是单纯地以8bit为单位保存它们,且每个字节可以是任意数字,包括0。这就意味着我们可以用字符串保存任意二进制数据。也可以将Unicode字符串保存为任意表示方式(UTF-8,UTF-16等等);但是,下面会谈到,尽可能使用UTF-8与有很多好处。Lua的标准字符串库假定了字符最少占一个字节,这与UTF-8有良好的兼容性。进一步说,从5.3版本开始,Lua内置了一个小的处理UTF-8编码的库。


   Lua中的字符串是不可变的(immutable)。不可能单独修改字符串中的一个字符,像C语言那样。而是需要创建一个新的字符串,且将它创建为你想要的样子:

1 a    =    "one string"    
2 b    =    string.gsub(a,    "one", "another")  -- 修改部分字符
3 print(a)    -->    one string
4 print(b)    -->    another string

   Lua中的字符串是自动内存管理的对象,与其它Lua对象相同(表、函数等等)。这意味着不需要关心字符串空间的申请和释放;Lua已经为我们处理好了。


  • 获取字符串的长度

   可以使用取长度运算符获取字符串的长度(写作“#”)。

1 a = "hello"        
2 print(#a)          -->    5
3 print(#"good bye")    -->    8

也可以用string.len()方法:

1 a = "hello"        
2 print(string.len(a))         --> 5
3 print(string.len("good bye"))--> 8

   这两个结果都是一样的。

取长度的结果总是以字节数表示,在不同的编码下可能与实际表示的字符数不同。


  • 字符串的连接

  

   可以通过字符串连接运算符“..”(两个点)来连接两个字符串。如果其中一个操作数是数字,那么就会将数字转为字符串并连接:

1 "Hello " .. "World"    --> Hello World
2 
3 "result is " .. 3     --> result is 3

   (某些语言使用加号连接字符串,但是3+5 和 3..5是不同的。)

   记住,Lua中的字符串是不可变对象。连接操作总是产生一个新的字符串,而不会修改原有的字符串

1 a    = "Hello"            
2 a    .. " World"  -->    Hello World
3 a              -->    Hello    

  • Literal strings字符串字面量

  

   使用单引号或双引号,可以创建一个字符串,其内容就是引号内的部分:

a = "a line"

b = 'another line'

   以上两种写法完全等价;唯一的区别是,在单引号表示的字符串内部,可以放心地使用双引号而不需要转义字符;反之也是同样的。

为了统一风格,大部分程序编写者会对同种类的字符串使用同样的引号,这种字符串的“种类”取决于具体的程序。例如,一个处理XML的程序会为表示XML字段的字符串使用单引号,因为这些字段内往往会包含双引号。

   Lua中的字符串,支持C风格的转义字符:

\a

bell

\b

back space

\f

form feed

\n

newline

\r

carriage return

\t

horizontal tab

\v

vertical tab

\\

backslash

\"

double quote

\'

single quote

   转义字符的示例如下:

 1 print("one line\nnext line\n\"in quotes\", 'in quotes'")
 2 -->one line
 3 -->next line
 4 -->"in quotes", 'in quotes'
 5 
 6 print('a backslash inside quotes: \'\\\'')
 7 -->a backslash inside quotes: '\'
 8 
 9 print("a simpler way: '\\'") 
10 -->a simpler way: '\'

   (看晕了....

   我们同样可以用数字的方式来表示字符串中的一个字符,形式为\ddd和\xhh,其中ddd三位数字,而hh是两个16进制数字。

   举一个刻意的例子:字符串”ALO\n123\””与字符串’\x41LO\10\04923’具有同样的值,在符合ASCII规范的系统中,0x41(即十进制的65)是字符A的编码,10是换行符的编码,而49是数字字符1的编码(这里注意必须写作\049,因为后面跟着的还是一个数字,会造成歧义,被误认为是\492)。

   我们还可以把以上字符串写作’\x41\x4c\x4f\x0a\x31\x32\x33\x22’,将每个字符都用十六进制编码表示。

   (这段翻译可能有问题,原文如下

We can specify a character in a literal string also by its numeric value through the escape sequences \ddd and \xhh, where ddd is a sequence of up to three decimal digits and hh is a sequence of exactly two hexadecimal digits. As a somewhat artificial example, the two literals "ALO\n123\"" and '\x41LO \10\04923"' have the same value in a system using ASCII: 0x41 (65 in decimal) is the ASCII code for A, 10 is the code for newline, and 49 is the code for the digit 1. (In this example we must write 49 with three digits, as \049, because it is followed by another digit; otherwise Lua would read the escape as \492.) We could also write that same string as '\x41\x4c\x4f\x0a\x31\x32\x33\x22', representing each character by its hexadecimal code.

   从Lua 5.3版本开始,还可以用\u{h...h}的方式指定UTF-8编码的字符串;在大括号内可以写上任意数量的十六进制数字以表示一串字符:

1 "\u{3b1} \u{3b2} \u{3b3}" --> # # #

   (以上例子假设是在一个UTF-8终端中执行的。)


  • 长字符串

   我们还可以使用两个方括号来定义一个字符串,类似多行注释那样。

   这种方式定义的字符串可以跨多行且不需要转义字符。而且如果第一个字符是一个换行符,还会忽略第一个字符。这种定义字符串的方式对于编写很长的字符串非常方便,举例如下:

 1 page = [[
 2 <html>
 3     <head>
 4         <title>An HTML Page</title>
 5     </head>
 6     <body>
 7         <a href="http://www.lua.org">Lua</a>
 8     </body>
 9 </html>
10 ]]
11 io.write(page)

   有时候,其它代码也可能会用到两个连续的中括号,比如a = b[c[i]](注意结尾是]]),或是去包含已经被多行注释过的内容时也会有这个问题。要处理这种情况,只需要在两个左方括号之间加上任意数量的等号:例如[===[。这样一来,就必须要用同样等号数量的方括号来配对:]===],编译器会忽略掉等号数量不同的中括号。通过选择不同数量的等号,就可以去包含任意一段代码而不需要对它做出修改。这就解决了中括号冲突问题。  

   同样的方法也可以用于多行注释。例如如果一个注释以--[=[开始,那么就要以]=]结束。这种方法适用于多行注释发生嵌套的情形。

   长字符串非常适用于表示字面字符串的情况,但是不应当用它来表示非文本类的字符串。

   尽管长字符串可以包含不可打印的二进制字节,但是使用长字符串直接包含二进制数据是不合适的(比如说你的编辑器可能会有显示问题);甚至,回车符例如“\r\n”会被转换成“\n”。更好的方式是在表示二进制数据时,使用数字的转义字符,例如”\x13\x01\xA1\xBB”。但是,在字符串较长时,会导致一行源码内有一个非常长的字符串。(这里没有理解)对于这种情况,Lua 5.2版本提供了一个转义字符\z,它会跳过之后的所有空白类字符,直到第一个飞空白字符。如下面的例子:

1 data = "\x00\x01\x02\x03\x04\x05\x06\x07\z 
2         \x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"

   第一行结尾的\z的作用是,跳过第一行结尾的换行符和第二行开头的空白字符,直到下一个\x08,也就是说\x08紧接在\x07的后面。这种写法方便我们把一个很长的字符串写在多行里。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Bypass ngx_lua_waf SQL注入防御(多姿势)
0x00前言ngx\_lua\_waf是一款基于ngx\_lua的web应用防火墙,使用简单,高性能、轻量级。默认防御规则在wafconf目录中,摘录几条核心的SQL注入防御规则:select.(from|limit)(?:(union(.?)select))(?:from\Winformation_schema\W)这边
Stella981 Stella981
3年前
Lua程序设计之字符串精要
(摘自Lua程序设计)基本:Lua语言的字符串是一串字节组成的序列。在Lua语言中,字符使用8个比特位来存储。Lua语言中的字符串可以存储包括空字符在内的所有数值代码,这意味着我们可以在字符串中存储任意的二进制数据。Lua语言中的字符串是不可变值,我们不能像C语言中那样直接改变某个字符串中的某个字符,但是我们可以通过创建一个新字符
Stella981 Stella981
3年前
JavaScript常用函数
1\.字符串长度截取functioncutstr(str,len){vartemp,icount0,patrn/^\x00\xff/,strre"";for(vari
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这