Uli Köhler
Uli Köhler

Reputation: 13751

How to get the first character of a string in Lua?

Given a string s in Lua:

s = "abc123"

If the string is non-empty, I want to store the first character of this string in a variable s1, else store nothing.

I've tried the following, but both return nil:

s1 = s[1]
s1 = s[0]

How can I get the first character without using external Lua libraries?

Upvotes: 37

Views: 64715

Answers (5)

younes askour
younes askour

Reputation: 58

i saw the code of @x0r and i want to clarify what he did :

https://www.lua.org/manual/5.1/manual.html says in 2.8 – Metatables :

A metatable controls how an object behaves in arithmetic operations, order comparisons, concatenation, length operation, and indexing.

Values of all other types share one single metatable per type; that is, there is one single metatable for all numbers, one for all strings, etc.

so we can create an index metamethod for the string type and all variable of string type well have this new behaviour

to know more about the index metamethod check Programming in Lua Chapter 13. Metatables and Metamethods

Upvotes: 1

Snap Skull
Snap Skull

Reputation: 1

I made 3 functions for strings.

Also, yes, I know this post is a year old, and that it was already answered, but I still made a function for you.

(And I already know that uppercase and lowercase methods exist but I don't care.)

function toUppercase(originalString, printString)
    if printString ~= true and printString ~= false then
        printString = false
    end
    if printString == true then
        print(originalString:upper())
    else
        return originalString:upper()
    end
end

function toLowercase(originalString, printString)
    if printString ~= true and printString ~= false then
        printString = false
    end
    if printString == true then
        print(originalString:lower())
    else
        return originalString:lower()
    end
end

function toTitleCase(originalString, printString)
    if printString ~= true and printString ~= false then
        printString = false
    end
    changeString = originalString:gsub("%W%l", string.upper):sub(0)
    titleCase = changeString:sub(1, 1):upper() .. changeString:sub(2, #changeString)
    if printString == true then
        print(titleCase)
    else
        return titleCase
    end
end

Upvotes: -1

x0r
x0r

Reputation: 41

local string_meta = getmetatable('')

function string_meta:__index( key )
    local val = string[ key ]
    if ( val ) then
        return val
    elseif ( tonumber( key ) ) then
        return self:sub( key, key )
    else
        error( "attempt to index a string value with bad key ('" .. tostring( key ) .. "' is not part of the string library)", 2 )
    end
end

local str = "Hello"
print(str[1])

Upvotes: 3

Termininja
Termininja

Reputation: 7036

You can also use this shorter variant:

s:sub(1, 1)

Upvotes: 30

Uli Köhler
Uli Köhler

Reputation: 13751

You can use string.sub() to get a substring of length 1:

> s = "abc123"
> string.sub(s, 1, 1)
a

This also works for empty strings:

> string.sub("", 1, 1) -- => ""

Upvotes: 47

Related Questions