Mục lục

Cách sử dụng chuỗi trong Lua


Giới thiệu

Chuỗi trong Lua là một kiểu dữ liệu cơ bản được dùng để lưu trữ và xử lý dữ liệu văn bản. Chuỗi biểu diễn một dãy ký tự, bao gồm chữ cái, số, ký hiệu, khoảng trắng và các ký tự đặc biệt khác.

Trong Lua, chuỗi có thể được tạo ra bằng cách đặt văn bản vào trong dấu nháy đơn ( ' ), dấu nháy kép ( “ ) hoặc dấu phân cách chuỗi (Ngoặc kép vuông) để tạo chuỗi nhiều dòng. Ví dụ, “Hello, Mini World!” và 'Mini World is great!' đều là các cách biểu diễn chuỗi hợp lệ trong Lua.

Chuỗi có thể được gán cho biến, giúp bạn lưu trữ và xử lý dữ liệu văn bản. Ví dụ:

local str1 = 'This is a string.' 
local str2 = "This is also a string." 
local str = "Hello, " 
str = str .. "World!" -- Create a new string and assign it to str
print ( str ) -- Output "Hello, World!"   
local multilineString = [[
This is a multiline string.
It can contain multiple lines of text.
No need for escape characters.
]]
 
print(multilineString)  

Ví dụ về chuỗi theo ba cách trên như sau:

string1 = "Lua"
Chat:sendSystemMsg(" \" String1 is \" " .. string1,0)
 
string2 = 'Mini World'
Chat:sendSystemMsg(" \" String2 is \" " .. string2,0)
 
string3 = [["Lua Tutorial"]]
Chat:sendSystemMsg(" \" String3 is \" " .. string3,0)

Kết quả xuất ra khi chạy đoạn mã trên là:

 String 1 is Lua 
 String 2 is Mini World
 String 3 is Lua Tutorial   

Tính độ dài chuỗi

Trong Lua, bạn có thể tính độ dài của một chuỗi bằng cách sử dụng hàm string.len(). Độ dài của chuỗi thể hiện số lượng ký tự mà chuỗi đó chứa. Dưới đây là hướng dẫn từng bước cách tính độ dài chuỗi trong Lua:

Bước 1: Định nghĩa một chuỗi
Đầu tiên, hãy định nghĩa một biến chuỗi mà bạn sẽ dùng để tính độ dài. Ví dụ, bạn có thể đặt một biến tên là myString với giá trị là “Hello, Lua!”:

local myString = "Hello, Lua!"

Bước 2: Tính độ dài
Để tính độ dài chuỗi, bạn dùng hàm string.len(). Hàm này nhận vào một chuỗi và trả về độ dài của chuỗi đó. Ở đây, ta truyền biến myString vào hàm string.len():

local length = string.len(myString)

Bước 3: Hiển thị kết quả Để xem độ dài chuỗi vừa tính, bạn có thể in ra bảng điều khiển bằng hàm print():

print("The length of the string is: " .. length)

Ví dụ mã hoàn chỉnh: Tổng hợp lại, đây là ví dụ mã hoàn chỉnh:

-- Định nghĩa chuỗi
local myString = "Hello, Lua!"
 
-- Tính độ dài
local length = string.len(myString)
 
-- Hiển thị kết quả
print("The length of the string is: " .. length)

Kết quả: Khi chạy đoạn mã trên, kết quả in ra sẽ là:

The length of the string is: 12

:!: Tuy nhiên, hàm string.len() trong Lua dựa trên mã hóa ASCII, có nghĩa là nó đếm số byte trong một chuỗi. Nếu bạn sử dụng string.len() trên một chuỗi chứa các ký tự ngoài phạm vi ASCII hoặc các ký tự được mã hóa bằng nhiều byte trong UTF-8, kết quả có thể không chính xác.

Ví dụ: Nếu bạn muốn đếm độ dài một chuỗi không phải là tiếng Anh hoặc số, thì kết quả trả về có thể sai lệch.

Trong trường hợp này, bạn nên dùng utf8.len() thay cho string.len() khi làm việc với chuỗi chứa các ký tự được mã hóa UTF-8. Dưới đây là lý do và khi nào bạn nên sử dụng utf8.len():

  1. Xử lý ký tự UTF-8: UTF-8 là dạng mã hóa có độ dài thay đổi, cho phép biểu diễn các ký tự từ nhiều ngôn ngữ khác nhau. Một số ký tự UTF-8 có thể được biểu diễn bằng nhiều byte. Khi bạn làm việc với các chuỗi chứa ký tự UTF-8, việc dùng utf8.len() sẽ đảm bảo đếm đúng số lượng ký tự hiển thị.
  2. Đếm “Grapheme”: Trong một số ngôn ngữ, một ký tự hiển thị duy nhất (gọi là grapheme) có thể bao gồm nhiều mã code point. Ví dụ, trong các ngôn ngữ như tiếng Thái hoặc chữ Devanagari, một ký tự có thể được tạo nên từ nhiều phần. Hàm utf8.len() xử lý mỗi grapheme như một đơn vị duy nhất và trả về đúng số lượng ký tự hiển thị.
  3. Tính độ dài chính xác: string.len() chỉ đếm số byte trong chuỗi mà không quan tâm đến cách mã hóa. Điều này không phản ánh chính xác số lượng ký tự hoặc grapheme hiển thị trong chuỗi khi làm việc với UTF-8. Hàm utf8.len() sẽ trả về số lượng ký tự chính xác theo mã hóa UTF-8.

Dưới đây là ví dụ minh họa sự khác biệt giữa string.len()utf8.len():

local myString = "Café"
print(string.len(myString))    -- Output: 6
print(utf8.len(myString))      -- Output: 4

Trong ví dụ này, string.len() đếm tổng số byte trong chuỗi, bao gồm cả hai byte được dùng để biểu diễn ký tự “é” theo mã hóa UTF-8. Ngược lại, utf8.len() đếm chính xác số ký tự hiển thị (grapheme), nên kết quả là 4.
Tóm lại, Hãy dùng utf8.len() khi làm việc với các chuỗi chứa ký tự mã hóa UTF-8 để đảm bảo việc đếm số lượng ký tự hoặc grapheme được chính xác. Còn nếu chuỗi không chứa ký tự UTF-8 (chỉ toàn ký tự ASCII như chữ cái tiếng Anh, số, v.v.), thì bạn vẫn có thể dùng string.len() để tính độ dài chuỗi một cách đơn giản nha!


Xử lý chuỗi trong Lua

STT Phương thức & Cách dùng
1 string.upper(argument)
Chuyển tất cả các ký tự trong chuỗi thành chữ in hoa.
2 string.lower(argument)
Chuyển tất cả các ký tự trong chuỗi thành chữ thường.
3 string.gsub(mainString, findString, replaceString, num):
Trả về một chuỗi bằng cách thay thế `findString` bằng `replaceString` trong `mainString`.
mainString: chuỗi gốc
findString: ký tự cần thay thế
replaceString: ký tự thay thế
num: số lần thay thế (có thể bỏ qua, khi đó sẽ thay hết)
4 string.find(str, substr, [init, [plain]])
Tìm chuỗi `substr` trong chuỗi `str`. Nếu tìm thấy, trả về chỉ số bắt đầu và kết thúc của chuỗi con. Nếu không tìm thấy, trả về nil.
5 string.format(arg)
Trả về một chuỗi được định dạng, tương tự như printf trong ngôn ngữ C.
6 string.char(arg) và string.byte(arg[,int])
`char`: chuyển các số nguyên thành ký tự và nối chúng lại.
`byte`: chuyển ký tự thành giá trị số nguyên (có thể chỉ định ký tự, mặc định là ký tự đầu tiên).
7 string.len(arg)
Tính độ dài (số ký tự) của chuỗi.
8 string.rep(string, n)
Trả về chuỗi `string` được lặp lại `n` lần.
9 .. (toán tử nối chuỗi)
Dùng để nối hai chuỗi lại với nhau.
10 string.gmatch(str, pattern)
Trả về một hàm lặp. Mỗi lần gọi hàm sẽ trả về chuỗi con kế tiếp trong `str` phù hợp với `pattern`. Nếu không tìm thấy, trả về nil.
11 string.match(str, pattern, init)
Tìm chuỗi khớp đầu tiên trong `str` với `pattern`. `init` là tùy chọn, chỉ vị trí bắt đầu tìm (mặc định là 1). Nếu khớp:
– Có capture → trả về capture.
– Không có capture → trả về toàn bộ chuỗi khớp.
– Không khớp → trả về nil.

Dưới đây là các ví dụ cho từng hàm xử lý chuỗi đã liệt kê ở trên:

1. string.upper(argument)

local str = "hello world"
local result = string.upper(str)
print(result) -- Kết quả: "HELLO WORLD"

2. string.lower(argument)

local str = "Hello World"
local result = string.lower(str)
print(result) -- Kết quả: "hello world"

3. string.gsub(mainString, findString, replaceString, num)

local str = "Hello, World!"
local result = string.gsub(str, "o", "a")
print(result) -- Kết quả: "Hella, Warld!"

4. string.find(str, substr, [init, [plain]])

local str = "Hello, World!"
local startPos, endPos = string.find(str, "World")
print(startPos, endPos) -- Kết quả: 8 12

5. string.format(arg)

local name = "John"
local age = 30
local result = string.format("My name is %s and I am %d years old.", name, age)
print(result) -- Kết quả: "My name is John and I am 30 years old."

6. string.char(arg) và string.byte(arg[,int])

local str = string.char(65, 66, 67) -- Mã ASCII
print(str) -- Kết quả: "ABC"
 
local char = string.byte("A")
print(char) -- Kết quả: 65 (Mã ASCII)

7. string.len(arg)

local str = "Hello, World!"
local length = string.len(str)
print(length) -- Kết quả: 13

8. string.rep(string, n)

local str = "Hello!"
local result = string.rep(str, 3)
print(result) -- Kết quả: "Hello!Hello!Hello!"

9. .. (toán tử nối chuỗi)

local str1 = "Hello"
local str2 = "World"
local result = str1 .. " " .. str2
print(result) -- Kết quả: "Hello World"

10. string.gmatch(str, pattern)

local str = "The quick brown fox"
for word in string.gmatch(str, "%a+") do
    print(word)
end
-- Kết quả:
-- "The"
-- "quick"
-- "brown"
-- "fox"

11. string.match(str, pattern, init)

local str = "Hello, World!"
local match = string.match(str, "%a+")
print(match) -- Kết quả: "Hello"