4

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?

Kurtis Nusbaum
  • 30,445
  • 13
  • 78
  • 102

2 Answers2

2

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.)

  • Thanks! Out of curisoity, I changed `my_str .. "\n"` to just `my_str` and that seemed to get rid of my extra newline at the end issue and give me the output I wanted. Why did you add the extra new line there? – Kurtis Nusbaum May 19 '22 at 15:59
  • 1
    @KurtisNusbaum Because if there's no newline at all on the end, then you'd lose the whole last line. – Joseph Sible-Reinstate Monica May 19 '22 at 16:26
  • ah, ok. That makes sense. In my usecase the string `my_str` is always guaranteed to have a newline as the last character. So that's probably why it works for me. Good to know about this little bit of safety though! – Kurtis Nusbaum May 19 '22 at 18:14
2

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")
DarkWiiPlayer
  • 6,871
  • 3
  • 23
  • 38