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.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Luca93
  • 91
  • 6

3 Answers3

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.

lhf
  • 70,581
  • 9
  • 108
  • 149
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
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 1
    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. – Tom Blodget Aug 07 '13 at 18:08
  • @TomBlodget Lua string is a sequence of bytes. Processing Unicode in Lua itself is a far more broad subject to answer here. – Yu Hao Aug 08 '13 at 00:50
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.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135