37

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?

5
  • 1
    use "byte" function: s:byte(1) string library Commented Mar 7, 2017 at 14:17
  • @MikeV. Good idea, but only works for non-unicode strings. s="ö" ; s:byte(1) == 195 ; s:byte(2) == 164 Commented Mar 7, 2017 at 14:31
  • @MikeV. However string.sub() also doesn't work for unicode :-) Commented Mar 7, 2017 at 14:33
  • 4
    For UTF-8 strings: s1 = s:match"^.?[\128-\191]*" Commented Mar 7, 2017 at 14:48
  • Just wonder how does s[1] return nil without error? s is a string, not a table. Commented Oct 17, 2024 at 5:07

5 Answers 5

49

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) -- => "" 
Sign up to request clarification or add additional context in comments.

1 Comment

What about if it is not a string? if it is a cdata field... Any ideas...
30

You can also use this shorter variant:

s:sub(1, 1) 

Comments

4
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]) 

1 Comment

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)?
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

Comments

-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 

2 Comments

Thank you ! I think this is helpful for many people trying to understand Lua basics :-)
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 functionality

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.