Capitalize first letter of every word in Lua

11.9k views Asked by At

I'm able to capitalize the first letter of my string using:

str:gsub("^%l", string.upper)

How can I modify this to capitalize the first letter of every word in the string?

4

There are 4 answers

1
n1xx1 On BEST ANSWER

I wasn't able to find any fancy way to do it.

str = "here you have a long list of words"
str = str:gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)
print(str)

This code output is Here You Have A Long List Of Words. %w* could be changed to %w+ to not replace words of one letter.


Fancier solution:

str = string.gsub(" "..str, "%W%l", string.upper):sub(2)

It's impossible to make a real single-regex replace because lua's pattern system is simple.

0
Alex Angel On

I have a feeling I will be returning to this question when I need to put something in proper title case.

Below is the Lua code to do exactly that. It has the disadvantage of not preserving the original spacing between words but it's good enough for now.

-- Lua is like python in syntax, and barebones like C -_-
function Set (list)
    local set = {}
    for _, l in ipairs(list) do set[l] = true end
    return set
end

function firstToUpper(str)
    return (str:gsub("^%l", string.upper))
end

function titlecase(str)
    -- We need to break the string into pieces
    words = {}
    for word in string.gmatch(str, '([^%s]+)') do
        table.insert(words, word)
    end

    -- We need to capitalize anything that is not a:
    --   - Article
    --   - Coordinating Conjunction
    --   - Preposition
    -- Thus we have a blacklist of such words
    local blacklist = Set {
        "at", "but", "by", "down", "for", "from", 
        "in", "into", "like", "near", "of", "off",
        "on", "onto", "out", "over", "past", "plus",
        "to", "up", "upon", "with", "nor", "yet",
        "so", "the"
    }
    for index, word in pairs(words) do
        if(not (blacklist[word] ~= nil)) then
            words[index] = firstToUpper(word)
        end
    end

    -- First and last words are always capitalized
    words[1] = firstToUpper(words[1])
    words[#words] = firstToUpper(words[#words])

    -- Concat elements in list via space character
    local result = ""
    for index, word in pairs(words) do
        result = result .. word
        if(index ~= #words) then
            result = result .. ' '
        end
    end
    return result
end

print(titlecase("the world"))
print(titlecase("I walked my dog this morning ..."))
print(titlecase("The art of Lua"))

--- Output:
----------------------
--- The World
--- I Walked My Dog This Morning ...
--- The Art of Lua

0
lkjhgfdsa On
function titleCase( first, rest )
   return first:upper()..rest:lower()
end

string.gsub(str, "(%a)([%w_']*)", titleCase)

BunchOfText {"Yeppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"}
1
Joe On

in the alternative answer listed you get inconsistent results with words containing apostrophes:

str = string.gsub(" "..str, "%W%l", string.upper):sub(2) will capitalize the first letter after each apostrophe irregardless if its the first letter in the word

eg: "here's a long list of words" outputs "Here'S A Long List Of Words"

to fix this i found a clever solution here

utilizing this code:

function titleCase( first, rest )
   return first:upper()..rest:lower()
end

string.gsub(str, "(%a)([%w_']*)", titleCase)

will fix any issues caused by that weird bug