มอดูล:string/gline
หน้าตา
- This module lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • transclusions • testcases • sandbox
local error = error
local find = string.find
local gmatch = string.gmatch
local sub = string.sub
--[==[
Iterates over the lines in a string, treating {"\n"}, {"\r"} and {"\r\n"} as new lines.
The optional {skip} parameter determines whether certain lines are skipped:
* {NONE}: none (default).
* {EMPTY}: empty lines: lines with a length of 0, consisting of no characters.
* {BLANK}: blank lines: empty lines and lines which only consist of whitespace characters.]==]
return function(str, skip)
-- Use gmatch() for EMPTY and BLANK, for speed.
if skip == "EMPTY" then
return gmatch(str, "[^\n\r]+")
elseif skip == "BLANK" then
return gmatch(str, "[^\n\r]-%S[^\n\r]*")
end
local start, pattern, plain, final = 1
if not (skip == nil or skip == "NONE") then
error("bad argument #2 to 'iterate_lines' (expected NONE, EMPTY or BLANK)", 2)
-- If the string contains \n and \r, use a comprehensive pattern; otherwise,
-- just look for the single characters with a plain match, which is much
-- faster. \r is very unlikely to be present, so look for it first.
elseif not find(str, "\r", nil, true) then
pattern, plain = "\n", true
elseif not find(str, "\n", nil, true) then
pattern, plain = "\r", true
else
pattern = "([\n\r]\n?)"
end
return function()
if final then
return
end
local pos1, pos2, newline = find(str, pattern, start, plain)
if not pos1 then
final = true
return sub(str, start)
end
local line = sub(str, start, pos1 - 1)
-- Advance `start` past `newline`. The comprehensive pattern will also
-- capture \n\n as a single match, so only advance past the first \n if
-- that happens; however, \r\n should be treated as a single new line.
start = newline == "\n\n" and pos2 or pos2 + 1
return line
end
end