Lua程序设计之字符串精要

Stella981
• 阅读 604

(摘自Lua程序设计)

基本:

Lua语言的字符串是一串字节组成的序列。

在Lua语言中,字符使用8个比特位来存储。

Lua语言中的字符串可以存储包括空字符在内的所有数值代码,这意味着我们可以在字符串中存储任意的二进制数据。

Lua语言中的字符串是不可变值,我们不能像C语言中那样直接改变某个字符串中的某个字符,但是我们可以通过创建一个新字符串来达到修改的目的。

例如:

a = "one string"
b = string.gsub(a, "one", another)
print(a)  ---> one string
print(b)  --->another string

像Lua语言中的其他对象一样,Lua语言中的字符串也是自动内存管理的对象之一。这意味着Lua会自动给字符串分配和释放资源,不用开发人员担心。

我们可以使用长度操作符(#)来获取字符串的长度

例如:

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

我们可以使用连接操作符..(两个点)来进行字符串的连接,如果操作符中存在数值,那么Lua会把数值转换成字符串。

例如:

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

字符串是不可变量。字符串连接总是创建一个新字符串,而不会改变作为操作数的字符串。

字符串常量

我们可以使用一对双引号或单引号来声明字符串常量

a = "a line"
b = 'another line'

他们两者唯一的区别在于,使用双引号声明的字符串中出现单引号时,单引号可以不用转义;同理,使用单引号声明的字符串中出现双引号时,双引号不用转义。

Lua语言的字符串支持下列C语言风格的转义字符

\a 响铃
\b 退格
\f 换页
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\\ 反斜杠
\" 双引号
\' 单引号

长字符串/多行字符串

像长注释或多行注释一样,字符串可以使用两个方括号来声明长字符串/多行字符串,并且内容中的转义序列不会被转义。

此外,如果多行字符串中的第一个字符是换行符,那么这个换行符将会被忽略。多行字符在声明大段代码时非常方便。

page = [[
<html>
<head>
<head>
</head>
<body>
</body>
</html>
]]

有时字符串中可能有类似 a = b[c[i]]这样的内容(注意]]),或者字符串中可能有注释掉的代码。为了应对这些情况,可以在两个左方括号之间加上任意数量的等号,如[===[。这样,字符串常量只有在遇到了包含相等数量等号的两个右方括号时才会结束,即]===]。这种方法对注释同样有效。

强制转换类型

Lua在运行时提供了数值与字符串之间的自动转换。针对字符串的所有算术操作会尝试将字符串转换为数值。

Lua不仅仅在算术操作时进行这种强制类型的转换。还会在任何需要数值的情况下进行,例如函数math.sin

相反,当Lua语言发现在需要字符串的地方出现数值时,会自动把数值转换为字符串。

print(10 .. 20)

当在数值后紧接着使用字符串连接时,必须使用空格将他们分开,否则Lua会把第一个点当成小数点。

算术运算的规则就是只有在两个操作数都是整型时,结果才是整型。因此,由于字符串不是整型值,所以字符串参与的算术运算都被当作浮点处理

"10" + 1 ---> 11.0

如果需要显示的将一个字符串转换成数值,那么可以使用函数tonumber。当这个字符串的内容不能表示为有效数字时,该函数返回nil;否则就返回对应的整型或者浮点型。

tonumber("  -3") --> -3
tonumber("10e4") --> 100000.0
tonumber("10e") -->nul
tonumber("0x1.3p-4") -->0.07421875

默认情况下tonumber使用的是十进制,但是也可以指明使用二进制到三十六进制之间的任意进制

tonumber("100101", 2) -->37
tonumber("fff", 16) -->4095
tonumber("987", 8) -->nil

调用函数tostring可以将数值转换成字符串

print(tostring(10) == "10") ---> true

与算术操作符不同,比较操作符不会对操作数进行强制类型转换。请注意,"0"和0是不同的。此外,2<15明显明显为真,但"2" < "15"却为假(字母顺序)。为了避免出现不一致的结果,当比较操作符中混用了字符串和数值时,Lua会抛出异常。

字符串标准库

Lua语言处理字符串的能力完全来自于字符串标准库

一些简单的函数:

string.len(s) --返回字符串s的长度等价于#s
string.rep(s,n) --返回字符串重复n次的结果
string.reverse --用于字符串的翻转
string.lower(s) --返回一份s的副本,其中所有的大写字母都被转换成小写字母,其他字符保持不变
string。upper --与之相反

string.sub(s, i, j) 从字符串s中提取第i个到第j个字符(包括i,j),字符串的第一个索引为1.
该函数也支持负数索引,负数索引从字符串的结尾开始计数。索引-1代表字符串的最后一个字符,以此类推。

string.sub(s, 1, j) 得到的是字符串s中长度为j的前缀
string.sub(s, j, -1)得到的是字符串s中从第j个字符开始的后缀


字符串是不可改变的,若想改变
s = string.sub(s, 2, -2)

string.char()和string.byte()用于转换字符及其内部数值表示,函数string.char接受零个或多个整数作为参数,然后将每个整数转换成对应的字符,最后返回这些字符所连成的字符串

string.byte(s, i)返回字符串s中的第i个字符的内部数值表示,第二个参数是可选的
string.byte(s)返回字符串s中的第一个字符(如果字符串只有一个字符组成,那么就返回这个字符)的内部数值表示。
假定字符使用ASCII表示的:
print(string.char(97)) --> a
i = 99; print(string.char(i, i+1, i+2)) --> cde
print(string.byte("abc")) -->97
print(string.byte("abc", 2)) -->98
print(string.byte("abc, -1")) -->99

调用string.byte(s, i, j)返回索引i到j(包括)之间的所有字符的数值表示

一种常见的写法是{string.byte(s, 1, -1)}该表达式会创建一个由字符串s中的所有字符代码组成的表

函数string.format是用于进行字符串格式化和将数字输出为字符串的强大工具,该函数会返回第一个参数的副本,其中每一个指示符都会被替换为使用对应格式就行格式化后的对应参数。格式化中的指示符和c语言中的类似。

string.format("x = %d", 10) --> x = 10
string.format("x = %x", 200) --> x = c8
string.format("x = %f", 200) --> x = 200.000000
tag, title = "h1", "a title"
string.format("<%s>%s</%s>", tag, title, tag) --> <h1>a title</h1>

在百分号和字母之间可以包含用于控制格式细节的其他选项,例如,可以控制一个浮点数小数点的位数。

print(string.format("pi = %.4f", math.pi)) --> pi = 3.1416
d = 5; m = 11; y = 1990
print(string.format("%02d/%02d/%04d", d, m, y)) --> 05/11/1990

关于更多的指示符参阅C语言printf函数的相关文档。

可以使用冒号操作符像调用字符串的一个方法那样调用字符串标准库中的所有函数。

例如

string.sub(s, i, j) --相当于
s:sub(s, i, j)

string.upper(s) --相当于
s:upper()

函数string.find用于在指定字符串中进行模式搜索

string.find("hello world", "wor") --> 7    9
string.find("hello world", "war") -->nil

如果该函数在指定的字符串中找到了匹配的模式,则返回模式的开始和结束位置,否则返回nil。函数string.gsub()则把所有匹配的模式用另一个字符串替换:

string.gsub("hello world", "l", ".") -->he..o wor.d    3
string.gsub("hello world", "a", ".") -->hello world    0

该函数还会在第二个返回值中返回发生替换的次数

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
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
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Wesley13 Wesley13
2年前
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中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Stella981 Stella981
2年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Stella981 Stella981
2年前
Lua学习笔记_String(一)
   Lua中的字符串可以包含一个字母也可以是一整本书。用一个字符串表示100K甚至1M的内容在Lua中并不罕见。     在Lua中,字符串是字节的序列。Lua内核中不关心这些字节是什么编码格式。Lua只是单纯地以8bit为单位保存它们,且每个字节可以是任意数字,包括0。这就意味着我们可以用字符串保存任意二进制数据。也可以将Unicode字符串保存为任
Stella981 Stella981
2年前
JavaScript常用函数
1\.字符串长度截取functioncutstr(str,len){vartemp,icount0,patrn/^\x00\xff/,strre"";for(vari
Wesley13 Wesley13
2年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ
Stella981 Stella981
2年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x