Lua中string库以及应用

Lua中string库以及应用

一、不需要模式匹配的函数

1. string.byte() —— 字符转换为编码(ASCII码)

原型:string.byte (s [, i [, j] ])

函数返回字符s[i], s[i+1], ···, s[j]的内部数字编码(ASCII码),其中参数i的默认值是1,而参数j的默认值是i

local str = "012abcd"
print("\n常规1~4的编码(012a):")
print(string.byte(str,1,4))

-- 字符串处理库的所有函数都被放置在表string中,并且还为操作的字符串设置了元表,使得这些字符串有了一个指向表string的__idnex字段
print("\n面向对象的表现方式:")
print(str:byte(1,4))

print("\n使用负数索引(c,d):")
print(str:byte(-2,-1))

在这里插入图片描述

2. string.char() —— 将编码(ASCII码)转化为字符

原型:string.char(...)

接收0个或者多个参数,返回一个字符串,字符串长度等于参数个数,前提是每一参数作为ASCII码都有一个字符与之相对应,也就是说大部分的数字是无效的,

local str = "012abcd"
print("\n常规1~4的编码(012a):")
print(string.byte(str,1,4))

-- 字符串处理库的所有函数都被放置在表string中,并且还为操作的字符串设置了元表,使得这些字符串有了一个指向表string的__idnex字段
print("\n面向对象的表现方式:")
print(str:byte(1,4))

print("\n使用负数索引(c,d):")
print(str:byte(-2,-1))

在这里插入图片描述

3. string.format()——格式化字符串。

原型:string.format (formatstring, ···)

格式化的字符串和C语言的printf()一族的函数遵循相同的规则

各种参数选项的含义:

c(字符) d(有符号数字) e(指数形式标书数字,小数点后6位有效数字)

E(与e相同,在数字表示中用E代替e)f(不使用指数表示数字,小数点后6位数字)g(指数形式标书数字,保留6位有效数字)

G(与g相同,在数字表示中用E代替e)i(测试与d相同)

o(八进制打印) u(无符号数字) x(十六进制表示)

– q (可以显示几乎所有特殊字符,并且不需要特殊处理。)

-- 打印字符串
local retstr = string.format("\ntoday is %s", os.date())
print(retstr)
---普通的字符串如果遇到字符"\0"时将会被截断,想要不截断那就需要使用格式符%q来处理
local sourcestr = "ADGdfhhjfhjafhdf~fa\000fFAKLDSFklj897890"
print("\n原串: "..sourcestr)

local q_sourcestr = string.format("%q", sourcestr)
print("\n格式化后不会被截断 "..q_sourcestr)

在这里插入图片描述

4. string.lower()——大写转小写

5. string.upper()——小写转大写

6. string.rep()——字符串的复制拼接

原型:string.rep(s, n)

返回字符串s串联n次的所组成的字符串,参数s表示基础字符串,参数n表示赋值的次数。

7. string.reverse()——字符串的复制拼接

原型:string.reverse(s)

返回字符串s反序字符串

-- 普通字符串
local sourcestr = "I am a good person !"
print("\nsourcestr is : "..sourcestr)

-- 使用函数反转
local first_ret = string.reverse(sourcestr)
print("\nfirst_ret is : ")
print(first_ret)


-- 字符串里包括`\0`
local otherstr = "this is a string \0 hahaha "
print("\n\notherstr is : "..string.format("%q", otherstr))

-- 再次使用函数反转
first_ret = string.reverse(otherstr)
print("\nfirst_ret is : ")
print(string.format("%q", first_ret))

在这里插入图片描述

8. string.reverse()——字符串截取

原型:string.sub(s, i [, j])

返回: s中从第i个字符到第j个字符的子串,

特殊:string.sub(s, 1, j)是返回字符串长度为j的前缀, string.sub(s, -i)返回子串长度为i的原串的后缀。

local sourcestr = "prefix--de asdsdjjj\0dsfdf56\0mfa54--suffix"
print("\n显示源字符串", string.format("%q", sourcestr))

local first_sub = string.sub(sourcestr, 4, 25)
print("\n普通截取", string.format("%q", first_sub))

local second_sub = string.sub(sourcestr, 1, 8)
print("\n取8个长度", string.format("%q", second_sub))

local third_sub = string.sub(sourcestr, -10)
print("\n从后取10个", string.format("%q", third_sub))

local fourth_sub = string.sub(sourcestr, -100) --函数会选择最接近指定索引的的一个索引作为参数。
print("\n索引越界", string.format("%q", fourth_sub))

在这里插入图片描述

9. string.dump()——序列化字符串

原型:string.dump (function)

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。可以通过从存储区中读取或反序列化对象的状态,重新创建该对象

--自定义一个函数
local function custom_func(num1, num2)
    local ret = num1 + num2;
    print("\nnum1 = "..num1)
    print("num2 = "..num2)
    print("num1 + num2 = "..ret)
end

-- 将函数序列化
local func_content = string.dump(custom_func)
print("\nfunc_content = "..func_content)

-- 将转化后的字符串写入文件
local outfile = io.open("dumptest.txt", "w")
local outnum = outfile:write(func_content)
outfile:close()

-- 从文件总读取内容
local infile = io.open("dumptest.txt", "r")
local incontent = infile:read("*a")
infile:close()
print("\ninput content is "..incontent)

在这里插入图片描述

二、模式匹配的函数

模式匹配函数

在string库中功能最强大的函数是:string.find (字符串查找), string.gsub (全局字符串替换),and string.match() (字符串匹配).

与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式(也写作regexp)来进行模式匹配(译者:POSIX是unix的工业标准,regexp最初来源于unix,POSIX对regexp也作了规范)。

主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大。权衡之下,Lua中的模式匹配的实现只用了500行代码,当然这意味着不可能实现POSIX所规范的所有更能。然而,Lua中的模式匹配功能是很强大的,并且包含了一些使用标准POSIX模式匹配不容易实现的功能。

1. string.find()——字符串查找

原型:string.find (s, pattern [, init [, plain]])

s:目标串 ;pattern:查找串; init(可选):搜索的起始位置 ;plain(可选):模式匹配的开闭

匹配模式:如果开启了匹配模式(false), %d 会被认为 是查找一个数字, 关闭了(true),那就是查找有无 %d

返回:查找的第一个起始索引和结束索引,如果模式匹配子串被找到了,一个成功被找到的子串将会作为第三个返回值;返回 第三个值的条件,那就是参数pattern中必须包括字符"()",这是输出第三个返回值的必要条件。

    local i, j=string.find("456 hello world! 123", 'l')
    print("---查找 l----",i, j) 
    local i, j=string.find("456 hello world! 123", 'l',10)
    print("---查找 l(10)----",i, j) 
    local i, j=string.find(" hello 456 %d world! 123", '%d')
    print("---查找 %d(匹配模式默认开启)----",i, j)      -- 找到的是4的坐标
    local i, j=string.find(" hello 456 %d world! 123", '%d',1,true) 
    print("---查找 %d(匹配模式关闭)----",i, j)          -- 找到的是 %d 字符的坐标
    local i, j, val=string.find(" hello 456 %d world! 123", '(%d)') 
    print("---查找 %d----",i, j,val)          -- 加上() 可返回匹配模式查找到的数值

在这里插入图片描述

2. string.gsub()——查找子串并替换

原型:string.gsub (s, pattern, repl [,m])不会对原串有改动

s:目标串 pattern:模式串 repl:替换串(一个字符串、表、或者是函数) m : 表示替换多少个

返回:1:替换后的副本 2:匹配替换的次数

解释:这个函数会返回一个替换后的副本,原串中所有的符合参数pattern的子串都将被参数repl所指定的字符串所替换,如果指定了参数m,那么只替换查找过程的前m个匹配的子串,参数repl可以是一个字符串、表、或者是函数,并且函数可以将匹配的次数作为函数的第二个参数返回,接下来看看参数repl的含义:

如果参数repl是一个常规字符串,成功匹配的子串会被repl直接替换,如果参数repl中包含转移字符%,那么可以采用%n的形式替换,当%n中的n取值1-9时,表示一次匹配中的第n个子串,当其中的n为0时,表示这次匹配的整个子串,%%表示一个单独的%

如果参数repl是一个表,那么每次匹配中的第一个子串将会作为整个表的键,取table[匹配子串]来替换所匹配出来的子串,当匹配不成功时,函数会使用整个字符串来作为table的键值。

如果参数repl是一个函数,那么每一次匹配的子串都将作为整个函数的参数,取function(匹配子串)来替换所匹配出来的子串,当匹配不成功时,函数会使用整个字符串来作为函数的参数。如果函数的返回值是一个数字或者是字符串,那么会直接拿来替换,如果它返回false或者nil,替换动作将不会发生,如果返回其他的值将会报错。处。

    local x
    x = string.gsub("hello world", "o", "lua")
    print("\n全部替换的常规替换:",x)

    
    x = string.gsub("hello worold", "o", "lua",1)
    print("\n只替换一次的常规替换:",x)

    x = string.gsub("hello world", "(%w+)", "lua")
    print("\n正则表达式替换",x)

    -- 如果参数repl中包含转移字符%,那么可以采用%n的形式替换,
    -- 当%n中的n取值1-9时,表示一次匹配中的第n个子串,当其中的n为0时,表示这次匹配的整个子串,%%表示一个单独的%。

    x = string.gsub("hello world", "%w+", "%1")
    print("\n包含转义字符%的替换",x)

    x = string.gsub("hello world", "%w+", "%0 %0")
    print("\n用匹配出的完成串*2来替换第一次匹配的结果",x)

    x = string.gsub("hello world from c to lua", "(%w+) (%a+)", "%0 %2")
    print("\n使用一个完整匹配和一个匹配的第二个串来替换",x)

    -- 如果参数repl是一个函数,那么每一次匹配的子串都将作为整个函数的参数,
    -- 取function(匹配子串)来替换所匹配出来的子串,当匹配不成功时,函数会使用整个字符串来作为函数的参数。
    -- 如果函数的返回值是一个数字或者是字符串,那么会直接拿来替换,如果它返回false或者nil,替换动作将不会发生,
    -- 如果返回其他的值将会报错。

    x = string.gsub("4 + 5 = $return 4+5$", "%$(.-)%$", function (s)
          return load(s)()
        end)
    print("\n用自定义函数",x)

    local t = {name="lua", version="5.1"}
    x = string.gsub("$name-$version", "%$(%w+)", t)
    print("\n调用表来替换",x)

在这里插入图片描述

3. string.match()——高端匹配函数(找第一个,直接返回)

原型:string.match(s, pattern [, init])

s:目标串 pattern:模式串 init:匹配的起始位置

解释:返回一个迭代器函数,每一次调用这个函数,返回一个在字符串s找到的下一个符合pattern描述的子串。如果参数pattern描述的字符串没有找到,迭代函数返回nil

local aimStr = "ehre99wj=--=-*-/4mdqwl\0ds123fef"
print("\n目标串 = ".. aimStr)

-- 由第一组结果可以看出string.match()在遇到\0时不会停止查找,
-- 而是一直查找到字符串结尾。
local ret1= string.match( aimStr,"%d%d%d")
print("\n找连续的三个数字 = ".. ret1)

ret1= string.match( aimStr,"%d%a%a")
print("\n找数字字母字母 = ".. ret1)

ret1 =string.match( aimStr,"")
print("\n找空的 = ".. ret1)

ret1= string.match( aimStr,"%d%d",10)
print("\n从10后面找两个数字 = ".. ret1)

print(string.match("hello world", "h(ell)o wor"))      --ell
-- 如果pattern没有指定括号,将返回整个匹配内容,否则返回括号内
print(string.match("hello world", "hello"))

-- 模式匹配
print(string.match("hell1o- world", "(%w+)"))

在这里插入图片描述

三、拓展

1. Lua中实现字符串分割函数split

function split(input, delimiter)
    input = tostring(input)
    delimiter = tostring(delimiter)
    if (delimiter == "") then return false end
    local pos, arr = 0, {}
    for st, sp in function() return string.find(input, delimiter, pos, true) end do
        table.insert(arr, string.sub(input, pos, st - 1))
        pos = sp + 1
    end
    table.insert(arr, string.sub(input, pos))
    return arr
end

local retTable = split("1-2-3-4","-")
for i,v in ipairs(retTable) do
    print(v)
end

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值