(浅)Lua学习笔记_String(一)

   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的后面这种写法方便我们把一个很长的字符串写在多行里

猜你喜欢

转载自www.cnblogs.com/guoyujam/p/11420627.html