Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate individual characters in Lua string?

Tags:

lua

I have a string in Lua and want to iterate individual characters in it. But no code I've tried works and the official manual only shows how to find and replace substrings :(

str = "abcd" for char in str do -- error   print( char ) end  for i = 1, str:len() do   print( str[ i ] ) -- nil end 
like image 896
grigoryvp Avatar asked May 06 '09 10:05

grigoryvp


People also ask

Can you index strings in Lua?

When indexing a string in Lua, the first character is at position 1, not at position 0 as in C. Indices are allowed to be negative and are interpreted as indexing backwards from the end of the string. Thus, the last character is at position -1, and so on.

How do I remove the first letter of a string in Lua?

You cannot delete the first character of a string. Returns the substring of s that starts at i and continues until j; i and j can be negative. If j is absent, then it is assumed to be equal to -1 (which is the same as the string length)....


2 Answers

In lua 5.1, you can iterate of the characters of a string this in a couple of ways.

The basic loop would be:

for i = 1, #str do     local c = str:sub(i,i)     -- do something with c end 

But it may be more efficient to use a pattern with string.gmatch() to get an iterator over the characters:

for c in str:gmatch"." do     -- do something with c end 

Or even to use string.gsub() to call a function for each char:

str:gsub(".", function(c)     -- do something with c end) 

In all of the above, I've taken advantage of the fact that the string module is set as a metatable for all string values, so its functions can be called as members using the : notation. I've also used the (new to 5.1, IIRC) # to get the string length.

The best answer for your application depends on a lot of factors, and benchmarks are your friend if performance is going to matter.

You might want to evaluate why you need to iterate over the characters, and to look at one of the regular expression modules that have been bound to Lua, or for a modern approach look into Roberto's lpeg module which implements Parsing Expression Grammers for Lua.

like image 86
RBerteig Avatar answered Oct 05 '22 11:10

RBerteig


Depending on the task at hand it might be easier to use string.byte. It is also the fastest ways because it avoids creating new substring that happends to be pretty expensive in Lua thanks to hashing of each new string and checking if it is already known. You can pre-calculate code of symbols you look for with same string.byte to maintain readability and portability.

local str = "ab/cd/ef" local target = string.byte("/") for idx = 1, #str do    if str:byte(idx) == target then       print("Target found at:", idx)    end end 
like image 20
Oleg V. Volkov Avatar answered Oct 05 '22 11:10

Oleg V. Volkov