lua-字符串操作

参考链接

以下几点需要注意

  • Index begin with 1, when indexing a string
  • negative value is allowed and that’s mean from the end of the string

string.format (formatstring, ···)

string.format(formatstring, ...) 是 Lua 中用于格式化字符串的函数。它接受一个格式化字符串 formatstring 和一系列参数 ...,并返回根据格式化字符串生成的字符串。

formatstring 是一个包含转换说明符的字符串,用于指定输出字符串的格式。转换说明符由百分号(%)开头,后面跟着一个或多个字符,用于指定要格式化的数据类型和格式。

以下是一些常见的转换说明符:

  • %s: 格式化一个字符串参数。
  • %d%i: 格式化一个带符号的十进制整数参数。
  • %f: 格式化一个浮点数参数。
  • %c: 格式化一个字符参数。
  • %x%X: 格式化一个十六进制整数参数,小写或大写字母表示。

示例使用:

1
2
3
4
5
6
7
8
9
10
-- 格式化字符串
local formatted_str = string.format("Hello, %s! You are %d years old.", "Alice", 30)
print(formatted_str) -- Output: Hello, Alice! You are 30 years old.

-- 使用多个参数进行格式化
local pi = 3.14159
local radius = 5
local area = pi * radius * radius
local formatted_area = string.format("The area of a circle with radius %.2f is %.2f", radius, area)
print(formatted_area) -- Output: The area of a circle with radius 5.00 is 78.54

在这个示例中,我们使用了 string.format 函数来生成格式化的字符串。第一个例子中,我们使用了 %s%d 转换说明符来格式化字符串和整数。第二个例子中,我们使用了 %f 转换说明符来格式化浮点数,并指定了保留两位小数的格式。

string.byte - 转成ASCII

string.byte 是 Lua 中用于获取字符串中指定位置的字符的 ASCII 码值的函数。它可以接受一个字符串和一个可选的起始位置作为参数,并返回指定位置处字符的 ASCII 码值。

1
string.byte(s [, i [, j]])
  • s:要获取字符的字符串。
  • i(可选):起始位置,默认为 1。
  • j(可选):结束位置,默认为 i
1
2
3
4
5
local str = "Hello, Lua!"
local byte1 = string.byte(str, 1) -- 获取第一个字符的 ASCII 码值
print(byte1) -- Output: 72
local byte5 = string.byte(str, 5) -- 获取第五个字符的 ASCII 码值
print(byte5) -- Output: 111

在示例中,字符串 “Hello, Lua!” 中的第一个字符是 ‘H’,其 ASCII 码值是 72,而第五个字符是 ‘o’,其 ASCII 码值是 111。

如果不指定 ij 参数,则默认获取第一个字符的 ASCII 码值。如果字符串为空或 i 大于字符串长度,则返回 nil

string.char (···) ASCII转字符串

string.char 函数用于将 ASCII 码值转换为对应的字符。它可以接受一个或多个整数参数,并返回这些整数对应的字符组成的字符串。

1
string.char(n1, n2, ...)
  • n1, n2, …:要转换为字符的整数值。
1
2
3
4
5
local char1 = string.char(72)  -- 将 ASCII 码值 72 转换为字符
print(char1) -- Output: H

local char2 = string.char(65, 66, 67) -- 将 ASCII 码值 65, 66, 67 转换为字符
print(char2) -- Output: ABC

在示例中,string.char(72) 将 ASCII 码值 72 转换为字符 ‘H’,而 string.char(65, 66, 67) 将 ASCII 码值 65、66 和 67 转换为字符 ‘A’、‘B’ 和 ‘C’ 组成的字符串。

如果参数不是整数,string.char 将会将其转换为整数后再进行处理。超出 ASCII 码范围的值会被模 256 处理,因此 ASCII 码值的有效范围是 0 到 255。

string.dump (function [, strip])

string.dump(function [, strip]) 是 Lua 中的一个函数,用于将指定函数编译为二进制代码的字符串表示形式。

  • function: 要编译的 Lua 函数。
  • strip(可选参数):布尔值,表示是否剔除调试信息。如果为 true,则编译的二进制代码中将不包含调试信息,使得生成的二进制代码更加紧凑。默认为 false,即保留调试信息。

示例使用:

1
2
3
4
5
6
7
8
9
10
-- 定义一个简单的 Lua 函数
local function add(a, b)
return a + b
end

-- 将函数编译为二进制代码的字符串表示形式
local binary_str = string.dump(add)

-- 输出编译后的二进制代码字符串
print(binary_str)

这样就会打印出编译后的二进制代码的字符串表示形式。需要注意的是,string.dump 函数会将函数编译为与 Lua 版本相关的二进制代码格式,因此生成的二进制代码字符串可能不可移植,只能在相同 Lua 版本之间使用。

如何使用呢?

使用 string.dump 函数的主要目的是将 Lua 函数编译为二进制代码字符串,然后可以将这个字符串保存到文件中或通过网络传输,并在需要时重新加载这个函数。这在某些情况下可能会有用,比如需要在不同的 Lua 环境之间传递函数,或者需要对函数进行加密以保护知识产权。

下面是一个简单的示例,演示了如何使用 string.dump 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- 定义一个简单的 Lua 函数
local function add(a, b)
return a + b
end

-- 将函数编译为二进制代码的字符串表示形式
local binary_str = string.dump(add)

-- 保存二进制代码字符串到文件
local file = io.open("compiled_function.bin", "wb")
file:write(binary_str)
file:close()

-- 从文件中加载二进制代码字符串并恢复为函数
file = io.open("compiled_function.bin", "rb")
local loaded_binary_str = file:read("*all")
file:close()

-- 加载二进制代码字符串并将其转换为函数
local loaded_function = load(loaded_binary_str)

-- 调用恢复的函数
local result = loaded_function(10, 20)
print(result) -- Output: 30

在这个示例中,我们首先定义了一个名为 add 的简单 Lua 函数。然后,使用 string.dump 函数将这个函数编译为二进制代码的字符串表示形式,并将其保存到文件 "compiled_function.bin" 中。接着,我们从文件中读取这个二进制代码字符串,并使用 load 函数将其加载为函数。最后,我们调用恢复的函数,并传入参数进行计算。

需要注意的是,load 函数加载的函数是匿名函数,因此我们将其赋值给一个变量以便后续调用。此外,加载的函数可能不会保留原始函数的上值(upvalues),因此在实际使用中需要注意。

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

string.find(s, pattern [, init [, plain]]) 是 Lua 中用于在字符串 s 中查找匹配 pattern 的模式的函数。它返回匹配的起始索引和结束索引(如果找到了),如果未找到匹配,则返回 nil

  • s: 要搜索的目标字符串。
  • pattern: 要匹配的模式字符串。
  • init(可选参数): 起始搜索位置,默认为 1。如果指定了 initfind 将从指定位置开始搜索。
  • plain(可选参数): 布尔值,表示是否关闭模式匹配。如果为 true,则会关闭模式匹配,pattern 将被视为普通字符串而非模式。默认为 false,即启用模式匹配。

示例使用:

1
2
3
4
5
6
7
8
9
10
11
local s = "Hello, Lua!"
local pattern = "Lua"

-- 在字符串 s 中查找模式 pattern
local start, finish = string.find(s, pattern)

if start then
print("Pattern found at position:", start, "-", finish)
else
print("Pattern not found.")
end

这个示例中,字符串 s 中的模式 "Lua" 被查找。如果找到了,则打印出匹配的起始和结束索引,否则打印 "Pattern not found."

string.gmatch (s, pattern [, init])

string.gmatch(s, pattern [, init]) 是 Lua 中用于迭代匹配字符串中所有模式的函数。它返回一个迭代器函数,每次调用都会返回下一个匹配项的位置和值,直到没有匹配项为止。

  • s: 要搜索的目标字符串。
  • pattern: 要匹配的模式字符串。
  • init(可选参数): 起始搜索位置,默认为 1。如果提供了 init 参数,gmatch 将从指定位置开始搜索。

示例使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local s = "Lua is a powerful scripting language."
local pattern = "%a+"

-- 使用 gmatch 迭代匹配所有单词
for word in string.gmatch(s, pattern) do
print(word)
end

-- Output:
-- Lua
-- is
-- a
-- powerful
-- scripting
-- language

在这个示例中,我们使用 string.gmatch 函数迭代匹配字符串 s 中的所有单词。模式 "%a+" 匹配一个或多个字母字符。每次迭代,迭代器函数返回下一个匹配的单词,直到没有更多匹配项为止。

string.gsub (s, pattern, repl [, n])

string.gsub(s, pattern, repl [, n]) 是 Lua 中用于全局替换字符串中模式匹配项的函数。它返回一个新的字符串,其中所有匹配模式 pattern 的子串都被替换为 repl

  • s: 要进行替换操作的目标字符串。
  • pattern: 要匹配的模式字符串。
  • repl: 替换字符串。可以是一个字符串或一个函数。
  • n(可选参数): 最多替换的次数。如果提供了 n,则只替换前 n 个匹配项。默认情况下,所有匹配项都会被替换。

如果 repl 是一个字符串,则它会简单地替换匹配的子串。如果 repl 是一个函数,则在每次匹配时调用该函数,将匹配的子串作为参数传递给它,然后用它的返回值替换匹配的子串。

示例使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
local s = "Lua is a powerful scripting language. Lua is fun!"
local pattern = "Lua"
local repl = "Python"

-- 全局替换所有匹配项
local replaced_str = string.gsub(s, pattern, repl)
print(replaced_str)
-- Output: Python is a powerful scripting language. Python is fun!

-- 替换前两个匹配项
local replaced_str_limit = string.gsub(s, pattern, repl, 2)
print(replaced_str_limit)
-- Output: Python is a powerful scripting language. Lua is fun!

-- 使用函数替换匹配项
local function upper_replace(match)
return match:upper()
end

local replaced_func_str = string.gsub(s, pattern, upper_replace)
print(replaced_func_str)
-- Output: LUA is a powerful scripting language. LUA is fun!

在这个示例中,我们使用了 string.gsub 函数来对字符串 s 进行全局替换。首先,我们简单地将所有匹配的 “Lua” 替换为 “Python”。然后,我们限制替换前两个匹配项。最后,我们使用一个函数将匹配的子串转换为大写。

string.len (s)

string.len(s) 是 Lua 中用于获取字符串长度的函数。它返回字符串 s 的长度,即其中包含的字符数(不包括末尾的空字符)。

  • s: 要获取长度的字符串。

示例使用:

1
2
3
local s = "Hello, Lua!"
local length = string.len(s)
print(length) -- Output: 12

在这个示例中,字符串 “Hello, Lua!” 包含 12 个字符,因此调用 string.len(s) 返回 12。

string.lower (s)

string.lower(s) 是 Lua 中用于将字符串转换为小写形式的函数。它返回字符串 s 的小写形式。

  • s: 要转换为小写的字符串。

示例使用:

1
2
3
local s = "Hello, Lua!"
local lower_str = string.lower(s)
print(lower_str) -- Output: hello, lua!

在这个示例中,字符串 “Hello, Lua!” 被转换为小写形式,并输出结果。

string.match (s, pattern [, init])

string.match(s, pattern [, init]) 是 Lua 中用于从字符串中查找第一个匹配模式的函数。它返回字符串 s 中第一个匹配模式 pattern 的子串,如果未找到匹配,则返回 nil

  • s: 要搜索的目标字符串。
  • pattern: 要匹配的模式字符串。
  • init(可选参数): 起始搜索位置,默认为 1。如果提供了 init 参数,match 将从指定位置开始搜索。

示例使用:

1
2
3
4
5
6
7
8
9
10
local s = "The quick brown fox jumps over the lazy dog."
local pattern = "%a+"

-- 匹配第一个单词
local match = string.match(s, pattern)
print(match) -- Output: The

-- 从第10个字符开始匹配
local match_init = string.match(s, pattern, 10)
print(match_init) -- Output: brown

在这个示例中,我们使用 string.match 函数从字符串 s 中查找第一个匹配模式 %a+ 的子串,这个模式匹配一个或多个字母字符。第一个调用返回字符串的第一个单词 “The”,而第二个调用从第 10 个字符开始搜索并返回第二个单词 “brown”。

string.sub (s, i [, j])

string.sub 是 Lua 中一个用于截取字符串的函数。它的详细用法如下:

语法

1
string.sub(s, i [, j])
  • s:要操作的字符串。
  • i:截取的起始位置(包含)。
  • j:(可选)截取的结束位置(包含),如果省略,则默认为字符串的末尾。

参数细节

  • 起始位置 i:可以是正数或负数。
    • 正数表示从字符串的第 i 个字符开始。
    • 负数表示从字符串的倒数第 |i| 个字符开始。
  • 结束位置 j:可以是正数或负数。
    • 正数表示到字符串的第 j 个字符结束。
    • 负数表示到字符串的倒数第 |j| 个字符结束。
    • 如果省略 j,则表示到字符串的末尾。

返回值

  • 返回一个新的字符串,它是从位置 ij 之间的子串(包括 ij)。

示例

以下是一些示例来说明 string.sub 的用法:

基本用法

1
2
3
4
local s = "Hello, World!"
print(string.sub(s, 1, 5)) -- 输出: Hello
print(string.sub(s, 8)) -- 输出: World!
print(string.sub(s, -6, -2))-- 输出: World

使用正数索引

1
2
3
local s = "abcdef"
print(string.sub(s, 2, 4)) -- 输出: bcd
print(string.sub(s, 3)) -- 输出: cdef

使用负数索引

1
2
3
local s = "abcdef"
print(string.sub(s, -4, -2))-- 输出: cde
print(string.sub(s, -3)) -- 输出: def

省略 j 参数

1
2
3
local s = "abcdef"
print(string.sub(s, 3)) -- 输出: cdef
print(string.sub(s, -3)) -- 输出: def

注意事项

  • 索引 ij 是从 1 开始的,而不是从 0 开始(这是与某些其他编程语言的区别)。
  • 如果 ij 超出字符串的范围,Lua 不会报错,而是会尽可能地返回有效的子串。

通过这些示例和说明,可以更清楚地理解 string.sub 的用法及其在字符串操作中的强大功能。

// TODO @lingxiao

  1. lua 中 Patterns 的应用

lua-字符串操作
https://jackiedai.github.io/2024/05/11/004lua/lua-字符串操作/
Author
lingXiao
Posted on
May 11, 2024
Licensed under