# Developers Planet

Quiloos39 February 2016

### Lua string pattern

Here is my code:

``````local code = [[
local a = 1

local b = 2
]]

local y = 0

for Paragraph in string.gmatch(code,"[^\n]+") do
print(Paragraph)
for Word in string.gmatch(Paragraph, "[^ ]+") do

end
y = y + 1
end
``````

The problem is pattern doesn't recognize my empty paragraphs how can i fix this ?

If you run the code you will what i mean

Output is:

``````local a = 1
local b = 2
``````

``````--space
local a = 1
--space
local b = 2
--space
``````

EinsteinK February 2016

This should do the trick:

``````local y,code = 0,[[

local a = 123

local b = 456

local c = "too much newlines because we're cool"
]]

local i = 1
local sigh = code:match("\n+")
y = y + #sigh
-- debug printing of newlines
for i=1,y do print() end
while true do
local start,stop = code:find("[^\n]+",i)
if not start then break end
local Paragraph = code:sub(start,stop)

-- Do your Paragraph parsing and stuff
print("PARAGRAPH:",Paragraph)

start,stop = code:find("\n+",stop+1)
if not stop then break end
y,i = y + stop - start + 1,stop+1
-- printing newlines to get the desired effect in output
for i=2,stop-start+1 do print() end
-- starting from 2 since the print(code:sub(...)) already prints one \n
end
-- reached end of the string
``````

It gives you this nice output:

``````PARAGRAPH:      local a = 123

PARAGRAPH:      local b = 456

PARAGRAPH:      local c = "too much newlines because we're cool"
``````

Tested at http://www.lua.org/cgi-bin/demo

Piglet February 2016

You don't get the empty line because you look for the complement of \n. If you only have \n in your line, there is no complement and you get no match.

You could use this pattern: "[^\n]*\n?" to get what you want. This pattern matches any line. So everything or nothing that is not a \n which is followed by 0 or 1 instances of \n

Nick Gammon February 2016

``````    --space
local a = 1
``````

You won't get that first space because Lua long strings discard the first newline.

Your problem is that your match on `"[^\n]+"` matches at least one character which is not a newline. An empty line won't match (there are no characters between the newlines) and thus they don't get shown.

Now you can change that to `"[^\n]*"` like this:

``````for Paragraph in string.gmatch(code,"[^\n]*") do
print("Line=", Paragraph)
for Word in string.gmatch(Paragraph, "[^ ]+") do
print ("Word=", Word)
end
end
``````

But that has a different problem:

``````Line=     local a = 1
Word= local
Word= a
Word= =
Word= 1
Line=
Line=
Line=     local b = 2
Word= local
Word= b
Word= =
Word= 2
Line=
Line=
``````

Blank lines appear twice!

A handy function for iterating through a string, a line at a time, is this:

``````function getlines (str)

local pos = 0

-- the for loop calls this for every iteration
-- returning nil terminates the loop
local function iterator (s)

if not pos then
return nil
end -- end of string, exit loop

local oldpos = pos + 1  -- step past previous newline
pos = string.find (s, "\n", oldpos) -- find next newline

if not pos then  -- no more newlines, return rest of string
return string.sub (s, oldpos)
end -- no newline

return string.sub (s, oldpos, pos - 1)

end -- iterator

return iterator, str
end -- getlines
``````

That handles empty lines. Now you can write your code like this (assuming the function above precedes your code):

``````for Paragraph in getlines (code) do
print("Line=", Paragraph)
for Word in string.gmatch(Paragraph, "[^ ]+") do
print ("Word=", Word)
end
end
``````

Output:

`              `