string.upper() / string.lower()
Lua's string.upper() and string.lower() convert the ASCII alphabetic characters in a string to uppercase or lowercase. They can also be called as methods (:upper() / :lower()), so the style can be chosen to suit the surrounding code.
Syntax
-- ----------------------------------------------- -- Function notation (via the string library) -- ----------------------------------------------- string.upper(s) -- returns s with all ASCII letters converted to uppercase string.lower(s) -- returns s with all ASCII letters converted to lowercase -- ----------------------------------------------- -- Method notation (via string metatable) -- ----------------------------------------------- s:upper() -- equivalent to string.upper(s) s:lower() -- equivalent to string.lower(s)
Function Reference
| Function | Description |
|---|---|
string.upper(s) | Returns a new string in which all ASCII lowercase letters (a–z) in s are converted to uppercase (A–Z). The original string is not modified. |
string.lower(s) | Returns a new string in which all ASCII uppercase letters (A–Z) in s are converted to lowercase (a–z). The original string is not modified. |
s:upper() | Method notation equivalent to string.upper(s). Available through Lua's string metatable. |
s:lower() | Method notation equivalent to string.lower(s). Available through Lua's string metatable. |
Sample Code
dragonball_upper_lower.lua
-- dragonball_upper_lower.lua — sample for string.upper() / string.lower()
-- Uses Dragon Ball characters to demonstrate case conversion
-- -----------------------------------------------
-- Basic case conversion
-- -----------------------------------------------
local hero = "Son Goku"
local villain = "Frieza"
-- Function notation
print("=== Function notation ===")
print(string.upper(hero)) -- SON GOKU
print(string.lower(villain)) -- frieza
-- Method notation produces the same result
print("")
print("=== Method notation ===")
print(hero:upper()) -- SON GOKU
print(villain:lower()) -- frieza
-- -----------------------------------------------
-- The original string is not modified (strings are immutable in Lua)
-- -----------------------------------------------
print("")
print("=== Original string is unchanged ===")
local name = "Vegeta"
local upper_name = name:upper()
print("Original: " .. name) -- Vegeta (unchanged)
print("Converted: " .. upper_name) -- VEGETA
-- -----------------------------------------------
-- Case-insensitive string comparison
-- -----------------------------------------------
print("")
print("=== Case-insensitive comparison ===")
local function eq_ignore_case(a, b)
-- Normalize both strings to lowercase before comparing
return a:lower() == b:lower()
end
local input1 = "PICCOLO"
local input2 = "piccolo"
local input3 = "Gohan"
if eq_ignore_case(input1, input2) then
print(input1 .. " and " .. input2 .. " are the same name")
end
if not eq_ignore_case(input1, input3) then
print(input1 .. " and " .. input3 .. " are different names")
end
-- -----------------------------------------------
-- Bulk conversion of character names
-- -----------------------------------------------
print("")
print("=== Bulk uppercase conversion ===")
local characters = { "Son Goku", "Vegeta", "Son Gohan", "Piccolo", "Frieza" }
for i, chara in ipairs(characters) do
print(string.format(" %d. %s -> %s", i, chara, chara:upper()))
end
-- -----------------------------------------------
-- Normalize user input to lowercase for search
-- -----------------------------------------------
print("")
print("=== Lowercase normalization for search ===")
local db = { "Son Goku", "Vegeta", "Son Gohan", "Piccolo", "Frieza" }
local function search(query)
local q = query:lower()
local results = {}
for _, chara in ipairs(db) do
if chara:lower():find(q, 1, true) then
results[#results + 1] = chara
end
end
return results
end
local found = search("SON") -- uppercase query still matches "Son Goku" / "Son Gohan"
print("Search for \"SON\":")
for _, chara in ipairs(found) do
print(" Hit: " .. chara)
end
lua dragonball_upper_lower.lua === Function notation === SON GOKU frieza === Method notation === SON GOKU frieza === Original string is unchanged === Original: Vegeta Converted: VEGETA === Case-insensitive comparison === PICCOLO and piccolo are the same name PICCOLO and Gohan are different names === Bulk uppercase conversion === 1. Son Goku -> SON GOKU 2. Vegeta -> VEGETA 3. Son Gohan -> SON GOHAN 4. Piccolo -> PICCOLO 5. Frieza -> FRIEZA === Lowercase normalization for search === Search for "SON": Hit: Son Goku Hit: Son Gohan
Common Mistakes
Japanese and accented characters are not converted
string.upper() and string.lower() only convert ASCII alphabetic characters (a–z, A–Z). Hiragana, katakana, kanji, and accented Latin characters such as é or ñ are returned unchanged. No error is raised — the unconverted characters simply pass through silently.
-- The Japanese portion is silently skipped (no error, but no conversion either) local name = "Son Goku (孫悟空)" print(string.upper(name)) -- SON GOKU (孫悟空) <- Japanese part unchanged -- Accented characters are treated the same way local cafe = "Café" print(string.upper(cafe)) -- CAFé <- é is not converted
-- OK: use with the understanding that only ASCII letters are affected local label = "HP: full" print(string.upper(label)) -- HP: FULL (works as intended)
Forgetting to normalize both sides in a case-insensitive comparison
When doing a case-insensitive comparison, both strings must be converted to the same case. Converting only one side causes the comparison to fail.
-- NG: only one side is lowercased, so the comparison fails
local input = "VEGETA"
local target = "Vegeta"
if input:lower() == target then -- "vegeta" == "Vegeta" -> false
print("match")
else
print("no match") -- this branch is taken
end
-- OK: normalize both sides to lowercase before comparing
local input = "VEGETA"
local target = "Vegeta"
if input:lower() == target:lower() then -- "vegeta" == "vegeta" -> true
print("match")
end
Calling method notation when the receiver is nil causes an error
The method notation s:upper() can only be used when s is a string. If s is nil — for example, from a missing table key or an uninitialized variable — the call will raise an error.
-- NG: the value retrieved from the table is nil, then a method is called on it
local db = { name = "Piccolo" }
local result = db.title:upper() -- db.title is nil -> attempt to index a nil value
-- OK: check for nil before calling
local db = { name = "Piccolo" }
if db.title then
print(db.title:upper())
else
print("title is not registered")
end
Overview
string.upper() and string.lower() target only ASCII alphabetic characters (a–z, A–Z). Japanese and other multibyte characters are not affected and are returned as-is. Because Lua strings are immutable, the converted result is returned as a new string and the original variable is not changed. Method notation (s:upper()) is syntactic sugar provided through Lua's string metatable and is completely equivalent to string.upper(s). The idiomatic pattern for case-insensitive comparison is a:lower() == b:lower(). See also String Basics and string.find() / string.match().
If you find any errors or copyright issues, please contact us.