String Manipulation in Lua: Make the odd char uppercase
Asked Answered
N

3

5

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.

Nobel answered 7/8, 2013 at 12:20 Comment(1)
Note: Your example also changes characters to lower case!Caras
S
2

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
Sematic answered 7/8, 2013 at 13:6 Comment(2)
This assumes that the character set encoding has only one byte per character. If that's not the case then a bunch problems come into play, beginning with how to find every other character.Caras
@TomBlodget Lua string is a sequence of bytes. Processing Unicode in Lua itself is a far more broad subject to answer here.Sematic
E
5

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.

Essen answered 7/8, 2013 at 13:58 Comment(0)
S
2

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
Sematic answered 7/8, 2013 at 13:6 Comment(2)
This assumes that the character set encoding has only one byte per character. If that's not the case then a bunch problems come into play, beginning with how to find every other character.Caras
@TomBlodget Lua string is a sequence of bytes. Processing Unicode in Lua itself is a far more broad subject to answer here.Sematic
J
1

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.

Jiggle answered 7/8, 2013 at 12:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.