Nanfeng

Notes on software development, code, and curious ideas

Lua Strings: Literals, Concatenation, Bytes and UTF-8

Lua strings are immutable byte sequences. They may contain ordinary text, binary data, and zero bytes. An operation never modifies an existing string; it returns a new one.

1
2
3
4
local original = "one string"
local changed = original:gsub("one", "another")
print(original) -- one string
print(changed) -- another string

Literals and concatenation

Single- and double-quoted literals support escapes such as \n, \t, \\, and numeric byte escapes. Long brackets are convenient for multiline text:

1
2
3
4
5
6
local document = [[
first line
second line
]]

local label = "Lua " .. "strings"

Concatenating many fragments in a loop repeatedly creates intermediate strings. Collect fragments in a table and use table.concat(parts) for large output.

Length and conversion

1
2
3
4
print(#"Lua")              -- 3 bytes
print(tonumber("42")) -- 42
print(tonumber("ff", 16)) -- 255
print(tostring(3.14))

Arithmetic may coerce numeric strings in some Lua versions, but explicit tonumber is clearer and more portable. The length operator counts bytes, not Unicode characters.

Standard operations

1
2
3
4
5
local text = "Hello Lua"
print(text:sub(1, 5))
print(text:upper())
print(text:find("Lua", 1, true)) -- plain search
print(("x=%d"):format(12))

Other core functions include string.byte, string.char, string.rep, string.reverse, string.match, string.gmatch, and string.gsub.

Lua 5.3 and later include utf8 helpers such as utf8.len, utf8.codes, and utf8.char. They operate on UTF-8 code points, which are still not always the same as user-perceived characters. Use a Unicode library for normalization, locale-aware case conversion, or grapheme-cluster editing.

+