0Pricing
Lua Academy · 课时

字符串基础:连接和长度

使用 .. 进行连接,使用 # 获取长度,并使用 string.rep/reverse。

字符串基础:连接和长度 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

使用 .. 进行字符串拼接

Lua 使用 ..(两个点)进行字符串拼接。它可以处理字符串和数字(数字会自动转换)。与许多语言中的 + 不同,Lua 中的 + 只能用于算术运算——对字符串使用 + 会导致错误。

local first = "Hello"
local second = "World"
print(first .. ", " .. second .. "!")  -- Hello, World!

-- Numbers auto-converted
local age = 30
print("Age: " .. age)   -- Age: 30

-- Bad: print("x" + "y")  ERROR: arithmetic on string

长度运算符 #

# 运算符返回字符串的字节长度。对于 ASCII 字符串,这等于字符数。对于多字节 UTF-8 字符串,# 统计的是字节而非字符——一个 UTF-8 表情符号占 4 个字节。若要获取准确的字符长度,请使用 UTF-8 库。

print(#"hello")        -- 5
print(#"")             -- 0
print(#"café")         -- 5 (c,a,f,é=2bytes)

local s = "Lua"
for i = 1, #s do
  io.write(string.byte(s, i) .. " ")
end
print()  -- 76 117 97

string.rep 和 string.reverse

string.rep(s, n, sep) 使用可选的分隔符,将字符串 s 完整重复 n 次。string.reverse(s) 反转字符串的字节顺序。两者都会返回新字符串——Lua 字符串是不可变的。

print(string.rep("ab", 3))       -- ababab
print(string.rep("ha", 3, "-"))  -- ha-ha-ha
print(string.rep("x", 0))        -- (empty)
print(string.reverse("hello"))   -- olleh
print(string.reverse("12345"))   -- 54321

string.upper 和 string.lower

string.upper(s) 和 string.lower(s) 可以转换 ASCII 字符。它们不处理 Unicode——非 ASCII 字符会保持不变。进行不区分大小写的比较时,请先将两个字符串都转换为 lower。

print(string.upper("hello"))     -- HELLO
print(string.lower("WORLD"))     -- world
print(string.upper("Lua 5.4!"))  -- LUA 5.4!

-- Case-insensitive comparison
local a = "Hello"
local b = "hello"
print(a:lower() == b:lower())    -- true

冒号方法语法

可以使用冒号语法对字符串值调用字符串函数:使用 s:upper() 代替 string.upper(s)。这是因为字符串具有 __index = string 的元表,因此所有字符串库函数都可以作为方法供任意字符串访问。

local s = "  hello world  "
print(s:upper())         -- HELLO WORLD
print(s:len())           -- 15
print(s:rep(2, "|"))     -- same as string.rep(s,2,"|")

-- Chain calls
print(("lua"):upper():reverse())  -- AUL

字符串不可变性

Lua 字符串是不可变的。您不能直接修改其中的字符。每个字符串操作都会创建一个新字符串。在循环中进行大量拼接时,请使用表来累积各个部分,并在最后调用 table.concat——这比反复使用 .. 高效得多。

-- Efficient string building
local parts = {}
for i = 1, 5 do
  parts[i] = "item" .. i
end
local result = table.concat(parts, ", ")
print(result)  -- item1, item2, item3, item4, item5

-- Slow! Creates 5 intermediate strings:
-- local s = ""
-- for i = 1, 5 do s = s .. "item" .. i end

使用 table.concat 连接字符串

table.concat(t, sep, i, j) 使用分隔符将数组元素连接成字符串。它只能处理字符串和数字值——表或布尔值会导致错误。这是用许多部分构建字符串的最快方式。

local parts = {"one", "two", "three", "four"}
print(table.concat(parts, ", "))          -- one, two, three, four
print(table.concat(parts, " | ", 2, 3))  -- two | three

-- Building CSV
local row = {1, "Alice", 95, true}
-- Need tostring for non-string values:
for i, v in ipairs(row) do row[i] = tostring(v) end
print(table.concat(row, ","))

字符串比较

字符串按字节值进行字典序比较。在 ASCII 中,大写字母排在小写字母之前(A=65,a=97),因此 "Z" < "a" 为 true。若要进行不区分大小写的排序,请对两侧都使用 string.lower。

print("abc" < "abd")    -- true
print("abc" < "abcd")   -- true (shorter)
print("Z" < "a")        -- true (Z=90, a=97)
print("10" < "9")       -- true (lexicographic!)
print(10 < 9)           -- false (numeric)

-- Sort strings case-insensitively
local words = {"Banana","apple","Cherry"}
table.sort(words, function(a,b) return a:lower()<b:lower() end)
print(table.concat(words,", "))

tostring 和 tonumber

tostring(v) 会将任意值转换为其字符串表示形式。tonumber(s, base) 会将字符串解析为数字。如果解析失败,tonumber 会返回 nil,这与许多会抛出异常的语言不同。整数解析时,进制可以是 2 到 36。

print(tostring(42))        -- 42
print(tostring(true))      -- true
print(tostring(nil))       -- nil
print(tostring({1,2}))     -- table: 0x...

print(tonumber("3.14"))    -- 3.14
print(tonumber("0xff"))    -- 255 (hex)
print(tonumber("11",2))    -- 3 (binary)
print(tonumber("abc"))     -- nil (invalid)

字符串驻留

Lua 会对短字符串进行驻留:内容相同的字符串在内存中共享同一个对象。经过哈希检查后,对字符串使用 == 实际上就是比较指针,因此速度非常快。字符串驻留也意味着创建字符串会有少量开销(计算哈希值),但重复使用已有字符串不需要额外开销。

local s1 = "hello"
local s2 = "hel" .. "lo"

-- Same content, interned to same object
print(s1 == s2)   -- true
print(#s1)        -- 5

-- Long strings may not be interned
-- They are still compared correctly by value
local long1 = string.rep("x", 1000)
local long2 = string.rep("x", 1000)
print(long1 == long2)  -- true

快速检查

在 Lua 中,要从许多小片段构建一个长字符串,最高效的方法是什么?

回顾:字符串基础

要点:

  • .. 用于拼接;不要对字符串使用 +
  • #s 统计字节数(不是 Unicode 字符数)
  • s:upper()、s:lower()、s:rep(n, sep)、s:reverse()
  • 字符串不可变——每次操作都会返回一个新字符串
  • 使用表和 table.concat 构建大型字符串
  • 使用 tostring/tonumber 进行类型转换

常见问题解答

「字符串基础:连接和长度」课时是免费的吗?

是的 — 「字符串基础:连接和长度」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「字符串基础:连接和长度」这节课中我会学到什么?

使用 .. 进行连接,使用 # 获取长度,并使用 string.rep/reverse。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「字符串基础:连接和长度」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 字符串基础:连接和长度
  2. 查找和提取子字符串
  3. 使用 string.format 生成输出
  4. string.gsub 和 string.gmatch
← 返回 Lua Academy