Split a string on new lines, but include empty lines

Viewed 92

Let's say I have a string with the contents

local my_str = [[
line1
line2

line4
]]

I'd like to get the following table:

{"line1","line2","","line4"}

In other words, I'd like the blank line 3 to be included in my result. I've tried the following:

  local result = {};
  for line in string.gmatch(my_str, "[^\n]+") do
      table.insert(result, line);
  end

However, this produces a result which will not include the blank line 3.

How can I make sure the blank line is included? Am I just using the wrong regex?

2 Answers

Try this instead:

  local result = {};
  for line in string.gmatch(my_str .. "\n", "(.-)\n") do
      table.insert(result, line);
  end

If you don't want the empty fifth element that gives you, then get rid of the blank line at the end of my_str, like this:

local my_str = [[
line1
line2

line4]]

(Note that a newline at the beginning of a long literal is ignored, but a newline at the end is not.)

You can replace the + with *, but that won't work in all Lua versions; LuaJIT will add random empty strings to your result (which isn't even technically wrong).

If your string always includes a newline character at the end of the last line like in your example, you can just do something like "([^\n]*)\n" to prevent random empty strings and the last empty string.

In Lua 5.2+ you can also just use a frontier pattern to check for either a newline or the end of the string: [^\n]*%f[\n\0], but that won't work in LuaJIT either.

If you need to support LuaJIT and don't have the trailing newline in your actual string, then you could just add it manually:

string.gmatch(my_str .. "\n", "([^\n]*)\n")
Related