157 posts
Posted 23 May 2014 - 10:41 PM
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
570 posts
Posted 23 May 2014 - 10:49 PM
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
See theoriginalbit's answer.
Edited on 24 May 2014 - 07:23 AM
157 posts
Posted 23 May 2014 - 11: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?
Edited on 23 May 2014 - 08:58 PM
1281 posts
Posted 23 May 2014 - 11:07 PM
He forgot to add a + sign to his custom character class
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 like
text:gmatch("(.+)\n?")
would probably be enough
Personally i use string.find for this, so idk, it mgiht work, it might not. Give it a try i suppose.
Edited on 23 May 2014 - 09:08 PM
157 posts
Posted 23 May 2014 - 11: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
157 posts
Posted 23 May 2014 - 11: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
1281 posts
Posted 23 May 2014 - 11: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
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
7508 posts
Location
Australia
Posted 24 May 2014 - 01:23 AM
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
did you actually test your code before posting it to 'help'? I have a feeling you didn't!
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.concat
H 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 intended
Hello 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 on 23 May 2014 - 11:23 PM
570 posts
Posted 24 May 2014 - 09:23 AM
did you actually test your code before posting it to 'help'? I have a feeling you didn't!
No, I didn't. This seemed simple enough to me but it was a little late at night… a bit very late.
Anyway, sorry about that. Confidence is evil.