How could create perhaps like a for loop, or any type of code in a function that takes in a string and finds \n, removes them and splits all the strings in-between, so a string such as 123\nabc\n456 would be split into a table of {123, abc, 456}. I know how I could head with this, using string.match, string.sub, or perhaps something like this but I'm still somewhat not sure.
I need this for my API function that firstly if a parameters allows splitting at \n spots, it will split then split the string whrereit finds \n, and after that, it splits the string to the given area, if no area is given it will use screen's width as default. So a string 105 characters would be split into 51, 51 and 3 characters.
Regards
Augustas
Splitting String With \n Into Table of Strings
Started by augustas656, May 23 2014 09:41 PM
8 replies to this topic
#1
Posted 23 May 2014 - 09:41 PM
#2
Posted 23 May 2014 - 09:49 PM
local lines = {}
local text = "Hello\nWorld!"
--# [^\r?\n\r?] means "anything that isn't a new line, optionally prefixed or suffixed with a carriage return"
for match in text:gmatch("[^\\r?\\n\\r?]") do
lines[#lines + 1] = match
end
See theoriginalbit's answer.
Edited by Lignum, 24 May 2014 - 08:23 AM.
#3
Posted 23 May 2014 - 10:01 PM
Can you please explain what do yuo mean by optionally prefixed or suffixed with a carriage return?
Regards
Augustas
I'm sorry, your code splits my string into char after char, so like hello world is split into h, e, l, l, o, , w, o, r, l, d?
Regards
Augustas
I'm sorry, your code splits my string into char after char, so like hello world is split into h, e, l, l, o, , w, o, r, l, d?
Edited by augustas656, 23 May 2014 - 09:58 PM.
#4
Posted 23 May 2014 - 10:07 PM
He forgot to add a + sign to his custom character class
Personally i use string.find for this, so idk, it mgiht work, it might not. Give it a try i suppose.
text:gmatch("[^\\r?\\n\\r?]+")
Although i can't say wether it will work or not still, since i believe +-? and the like don't work the same way within custom classes. Something liketext:gmatch("(.+)\n?")
would probably be enoughPersonally i use string.find for this, so idk, it mgiht work, it might not. Give it a try i suppose.
Edited by CometWolf, 23 May 2014 - 10:08 PM.
#5
Posted 23 May 2014 - 10:19 PM
How do you (personally CometWolf) use string.find? I personally done something while there's an \n array[#array + 1] is equal to the string before \n, then string is string removed the first part including the \n. But the problem with that is it doesn't include the last remaining part of the string after the last \n.
Regards
Augustas
Regards
Augustas
#6
Posted 23 May 2014 - 10:27 PM
Okay I got it to work with the +, thanks, but can someone explain what Lignum meant by optionally prefixed or suffixed with a carriage return?
Regards
Augustas
Regards
Augustas
#7
Posted 23 May 2014 - 10:41 PM
"\r" is the character for carriage return, and the question mark means they are an optional match, ie. not needed. However i don't believe question marks work that way within custom classes([]).
For the record, here's the function i use
For the record, here's the function i use
string.lineFormat = function(text,lineLength,center)
local tLines = {}
while #text > 0 do --splits text into a table containing each line
local line = text:sub(1,lineLength)
local newLine = string.find(line.."","\n") --check for new line character
if newLine then
line = line:sub(1,newLine-1)
text = text:sub(#line+2,#text)
elseif #line == lineLength then
local endSpace = line:find"%s$" or line:find"%s%S-$" or lineLength
line = line:sub(1,endSpace)
text = text:sub(#line+1)
else
text = ""
end
if center then
line = string.rep(" ",math.max(math.floor((lineLength-#line)/2),0))..line
line = line..string.rep(" ",math.max(lineLength-#line,0))
end
tLines[#tLines+1] = line
end
return tLines
end
#8
Posted 24 May 2014 - 12:23 AM
Lignum, on 23 May 2014 - 09:49 PM, said:
You'd do something like this:
local lines = {}
local text = "Hello\nWorld!"
--# [^\r?\n\r?] means "anything that isn't a new line, optionally prefixed or suffixed with a carriage return"
for match in text:gmatch("[^\\r?\\n\\r?]") do
lines[#lines + 1] = match
end
adding a table.concat(lines, ' ') at the end of your script will show you why I think this... here's the output
H e l l o W o r l d !notice how the new line is still there, that is because you've escaped the backslash by doing \\ ... newline is \n or \r and the combinations of those two, so your loop should look like
for match in text:gmatch("[^\r?\n\r?]") do
lines[#lines + 1] = match
end
however that still 'causes one little problem, take a look at the output from the table.concatH e l l o W o r l d !now this output is because your pattern has it ignore new lines, however it only does that one character... CometWolf's response holds the answer, your loop should look like this
for match in text:gmatch("[^\r?\n\r?]+") do
lines[#lines + 1] = match
end
now if you take a look at the output from table.concat you'll notice it has worked as intendedHello World!
I don't like having to correct the 'pros' but sadly its getting to the point where 1) people either don't know what they're talking about when trying to help, or 2) they don't test their code before posting, a crucial step in making sure you provide accurate help, not just more problems and headaches for the OP.
Edited by theoriginalbit, 24 May 2014 - 12:23 AM.
#9
Posted 24 May 2014 - 08:23 AM
theoriginalbit, on 24 May 2014 - 12:23 AM, said:
did you actually test your code before posting it to 'help'? I have a feeling you didn't!
Anyway, sorry about that. Confidence is evil.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











