Capitalize first letter of every word in Lua
Asked Answered
E

4

13

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?

Eros answered 29/11, 2013 at 11:18 Comment(6)
From some googling "%f%l"?Penstemon
No go on the %f%l these regexes always get me in a new language.Eros
Ok, one last blind guess "%A%l" <- bah just realised even if this works as I'm thinking it might in my head, it still wouldn't capitalise the first letter of a string, only subsequent words.Penstemon
Closer! %A%l seems to grab the first letter of every word except for the first character of the string.Eros
See also #2422195.Ruberta
That's where I lifted my first example from. =]Eros
A
14

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.

Alvaalvan answered 29/11, 2013 at 11:43 Comment(1)
if you have a word with an apostrophe, it will capitalize the first letter after the apostrophe as well eg: "here's a long list of words" outputs "Here'S A Long List Of Words" - trying to find a fixRepertoire
R
3

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

Repertoire answered 21/3, 2014 at 1:51 Comment(1)
FYI, that link no longer works but there it is also a solution on this nifty little cheat sheetUnreserve
G
0
function titleCase( first, rest )
   return first:upper()..rest:lower()
end

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

BunchOfText {"Yeppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"}
Granicus answered 13/9, 2014 at 18:32 Comment(0)
S
0

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

Sahaptin answered 26/3, 2022 at 22:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.