(摘自Lua程序设计)
基本:
Lua语言的字符串是一串字节组成的序列。
在Lua语言中,字符使用8个比特位来存储。
Lua语言中的字符串可以存储包括空字符在内的所有数值代码,这意味着我们可以在字符串中存储任意的二进制数据。
Lua语言中的字符串是不可变值,我们不能像C语言中那样直接改变某个字符串中的某个字符,但是我们可以通过创建一个新字符串来达到修改的目的。
例如:
1a = "one string" 2b = string.gsub(a, "one", another) 3print(a) ---> one string 4print(b) --->another string
像Lua语言中的其他对象一样,Lua语言中的字符串也是自动内存管理的对象之一。这意味着Lua会自动给字符串分配和释放资源,不用开发人员担心。
我们可以使用长度操作符(#)来获取字符串的长度
例如:
1a = "hello" 2print(#a) ---> 5 3print(#"good bye") --->8
我们可以使用连接操作符..(两个点)来进行字符串的连接,如果操作符中存在数值,那么Lua会把数值转换成字符串。
例如:
1"Hello " .. "World" ---> Hello World 2"result is " .. 3 ---> result is 3
字符串是不可变量。字符串连接总是创建一个新字符串,而不会改变作为操作数的字符串。
字符串常量
我们可以使用一对双引号或单引号来声明字符串常量
1a = "a line" 2b = 'another line'
他们两者唯一的区别在于,使用双引号声明的字符串中出现单引号时,单引号可以不用转义;同理,使用单引号声明的字符串中出现双引号时,双引号不用转义。
Lua语言的字符串支持下列C语言风格的转义字符
1\a 响铃 2\b 退格 3\f 换页 4\n 换行 5\r 回车 6\t 水平制表符 7\v 垂直制表符 8\\ 反斜杠 9\" 双引号 10\' 单引号
长字符串/多行字符串
像长注释或多行注释一样,字符串可以使用两个方括号来声明长字符串/多行字符串,并且内容中的转义序列不会被转义。
此外,如果多行字符串中的第一个字符是换行符,那么这个换行符将会被忽略。多行字符在声明大段代码时非常方便。
1page = [[ 2<html> 3<head> 4<head> 5</head> 6<body> 7</body> 8</html> 9]]
有时字符串中可能有类似 a = b[c[i]]这样的内容(注意]]),或者字符串中可能有注释掉的代码。为了应对这些情况,可以在两个左方括号之间加上任意数量的等号,如[===[。这样,字符串常量只有在遇到了包含相等数量等号的两个右方括号时才会结束,即]===]。这种方法对注释同样有效。
强制转换类型
Lua在运行时提供了数值与字符串之间的自动转换。针对字符串的所有算术操作会尝试将字符串转换为数值。
Lua不仅仅在算术操作时进行这种强制类型的转换。还会在任何需要数值的情况下进行,例如函数math.sin
相反,当Lua语言发现在需要字符串的地方出现数值时,会自动把数值转换为字符串。
print(10 .. 20)
当在数值后紧接着使用字符串连接时,必须使用空格将他们分开,否则Lua会把第一个点当成小数点。
算术运算的规则就是只有在两个操作数都是整型时,结果才是整型。因此,由于字符串不是整型值,所以字符串参与的算术运算都被当作浮点处理
"10" + 1 ---> 11.0
如果需要显示的将一个字符串转换成数值,那么可以使用函数tonumber。当这个字符串的内容不能表示为有效数字时,该函数返回nil;否则就返回对应的整型或者浮点型。
1tonumber(" -3") --> -3 2tonumber("10e4") --> 100000.0 3tonumber("10e") -->nul 4tonumber("0x1.3p-4") -->0.07421875
默认情况下tonumber使用的是十进制,但是也可以指明使用二进制到三十六进制之间的任意进制
1tonumber("100101", 2) -->37 2tonumber("fff", 16) -->4095 3tonumber("987", 8) -->nil
调用函数tostring可以将数值转换成字符串
print(tostring(10) == "10") ---> true
与算术操作符不同,比较操作符不会对操作数进行强制类型转换。请注意,"0"和0是不同的。此外,2<15明显明显为真,但"2" < "15"却为假(字母顺序)。为了避免出现不一致的结果,当比较操作符中混用了字符串和数值时,Lua会抛出异常。
字符串标准库
Lua语言处理字符串的能力完全来自于字符串标准库
一些简单的函数:
1string.len(s) --返回字符串s的长度等价于#s 2string.rep(s,n) --返回字符串重复n次的结果 3string.reverse --用于字符串的翻转 4string.lower(s) --返回一份s的副本,其中所有的大写字母都被转换成小写字母,其他字符保持不变 5string。upper --与之相反 6 7string.sub(s, i, j) 从字符串s中提取第i个到第j个字符(包括i,j),字符串的第一个索引为1. 8该函数也支持负数索引,负数索引从字符串的结尾开始计数。索引-1代表字符串的最后一个字符,以此类推。 9 10string.sub(s, 1, j) 得到的是字符串s中长度为j的前缀 11string.sub(s, j, -1)得到的是字符串s中从第j个字符开始的后缀 12 13 14字符串是不可改变的,若想改变 15s = string.sub(s, 2, -2) 16 17string.char()和string.byte()用于转换字符及其内部数值表示,函数string.char接受零个或多个整数作为参数,然后将每个整数转换成对应的字符,最后返回这些字符所连成的字符串 18 19string.byte(s, i)返回字符串s中的第i个字符的内部数值表示,第二个参数是可选的 20string.byte(s)返回字符串s中的第一个字符(如果字符串只有一个字符组成,那么就返回这个字符)的内部数值表示。 21假定字符使用ASCII表示的: 22print(string.char(97)) --> a 23i = 99; print(string.char(i, i+1, i+2)) --> cde 24print(string.byte("abc")) -->97 25print(string.byte("abc", 2)) -->98 26print(string.byte("abc, -1")) -->99 27 28调用string.byte(s, i, j)返回索引i到j(包括)之间的所有字符的数值表示
一种常见的写法是{string.byte(s, 1, -1)}该表达式会创建一个由字符串s中的所有字符代码组成的表
函数string.format是用于进行字符串格式化和将数字输出为字符串的强大工具,该函数会返回第一个参数的副本,其中每一个指示符都会被替换为使用对应格式就行格式化后的对应参数。格式化中的指示符和c语言中的类似。
1string.format("x = %d", 10) --> x = 10 2string.format("x = %x", 200) --> x = c8 3string.format("x = %f", 200) --> x = 200.000000 4tag, title = "h1", "a title" 5string.format("<%s>%s</%s>", tag, title, tag) --> <h1>a title</h1>
在百分号和字母之间可以包含用于控制格式细节的其他选项,例如,可以控制一个浮点数小数点的位数。
1print(string.format("pi = %.4f", math.pi)) --> pi = 3.1416 2d = 5; m = 11; y = 1990 3print(string.format("%02d/%02d/%04d", d, m, y)) --> 05/11/1990
关于更多的指示符参阅C语言printf函数的相关文档。
可以使用冒号操作符像调用字符串的一个方法那样调用字符串标准库中的所有函数。
例如
1string.sub(s, i, j) --相当于 2s:sub(s, i, j) 3 4string.upper(s) --相当于 5s:upper()
函数string.find用于在指定字符串中进行模式搜索
1string.find("hello world", "wor") --> 7 9 2string.find("hello world", "war") -->nil
如果该函数在指定的字符串中找到了匹配的模式,则返回模式的开始和结束位置,否则返回nil。函数string.gsub()则把所有匹配的模式用另一个字符串替换:
1string.gsub("hello world", "l", ".") -->he..o wor.d 3 2string.gsub("hello world", "a", ".") -->hello world 0
该函数还会在第二个返回值中返回发生替换的次数