Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String Manipulation in Lua: Make the odd char uppercase

I'm trying to do a library in Lua with some function that manipulate strings. I want to do a function that changes the letter case to upper only on odd characters of the word.

This is an example:

Input: This LIBRARY should work with any string!
Result: ThIs LiBrArY ShOuLd WoRk WiTh AnY StRiNg!

I tried with the "gsub" function but i found it really difficult to use.

like image 536
Luca93 Avatar asked Aug 07 '13 12:08

Luca93


3 Answers

This almost works:

original = "This LIBRARY should work with any string!"
print(original:gsub("(.)(.)",function (x,y) return x:upper()..y end))

It fails when the string has odd length and the last char is a letter, as in

original = "This LIBRARY should work with any strings"

I'll leave that case as an exercise.

like image 160
lhf Avatar answered Nov 15 '22 10:11

lhf


First, split the string into an array of words:

local original = "This LIBRARY should work with any string!"

local words = {}
for v in original:gmatch("%w+") do 
    words[#words + 1] = v
end

Then, make a function to turn words like expected, odd characters to upper, even characters to lower:

function changeCase(str)
    local u = ""
    for i = 1, #str do
        if i % 2 == 1 then
            u = u .. string.upper(str:sub(i, i))
        else
            u = u .. string.lower(str:sub(i, i))
        end
    end
    return u
end

Using the function to modify every words:

for i,v in ipairs(words) do
    words[i] = changeCase(v)
end

Finally, using table.concat to concatenate to one string:

local result = table.concat(words, " ")
print(result)
-- Output: ThIs LiBrArY ShOuLd WoRk WiTh AnY StRiNg
like image 22
Yu Hao Avatar answered Nov 15 '22 10:11

Yu Hao


Since I am coding mostly in Haskell lately, functional-ish solution comes to mind:

local function head(str) return str[1] end
local function tail(str) return substr(str, 2) end

local function helper(str, c)
    if #str == 0 then
        return ""
    end

    if c % 2 == 1 then
        return toupper(head(str)) .. helper(tail(str),c+1)
    else
        return head(str) .. helper(tail(str), c+1)
    end
end

function foo(str) 
   return helper(str, 1)
end

Disclaimer: Not tested, just showing the idea.


And now for real, you can treat a string like a list of characters with random-access with reference semantics on []. Simple for loop with index should do the trick just fine.

like image 44
Bartek Banachewicz Avatar answered Nov 15 '22 08:11

Bartek Banachewicz