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

5

33

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?

Ritzy answered 7/3, 2017 at 14:3 Comment(4)
use "byte" function: s:byte(1) string libraryKrafftebing
@MikeV. Good idea, but only works for non-unicode strings. s="ö" ; s:byte(1) == 195 ; s:byte(2) == 164Cydnus
@MikeV. However string.sub() also doesn't work for unicode :-)Cydnus
For UTF-8 strings: s1 = s:match"^.?[\128-\191]*"Hawfinch
R
43

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) -- => ""
Ritzy answered 7/3, 2017 at 14:3 Comment(1)
What about if it is not a string? if it is a cdata field... Any ideas...Delve
A
29

You can also use this shorter variant:

s:sub(1, 1)
Anatomical answered 24/1, 2020 at 13:11 Comment(0)
J
3
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])
Jeniferjeniffer answered 14/7, 2020 at 18:24 Comment(1)
I don't think the OP was asking how to implement s[1], but how to get the first character. Also, could you add a bit more explanation on how the sample works, how to use it, and what the expected output should be (matching the original example)?Cooperative
F
1

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

Fluidize answered 17/5, 2024 at 13:9 Comment(0)
N
-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
Napoleonnapoleonic answered 3/4, 2023 at 1:1 Comment(2)
Thank you ! I think this is helpful for many people trying to understand Lua basics :-)Cydnus
StackOverflow is a platform where people try to give direct answers to the question. This answer is not clear. You show 3 functions, but only the last function does some manipulations with the first symbol, though it's complicated by other logic, thus it's not answering to the question directly. BTW, refactoring advice, if you remove the first if-blocks from every function, you will have the same functionalityDrummond

© 2022 - 2025 — McMap. All rights reserved.