这是我的代码:
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
问题是模式无法识别我的空段落如何解决这个问题?
如果您运行代码,您将是我的意思
输出是:
local a = 1
local b = 2
相反它应该是:
--space
local a = 1
--space
local b = 2
--space
答案 0 :(得分:1)
你没有得到空行,因为你找到\ n的补码。如果你的行中只有\ n,则没有补充,你就没有匹配。
您可以使用此模式:“[^ \ n] * \ n?”得到你想要的。 此模式匹配任何行。所以一切或者没有什么都不是\ n后面跟着0或1个\ n
的实例答案 1 :(得分:1)
相反它应该是:
--space local a = 1
你没有获得第一个空格,因为Lua长串丢弃了第一个换行符。
您的问题是"[^\n]+"
上的匹配与至少一个字符匹配,而该字符不是换行符。空行不匹配(换行符之间没有字符),因此无法显示。
现在您可以将其更改为"[^\n]*"
,如下所示:
for Paragraph in string.gmatch(code,"[^\n]*") do
print("Line=", Paragraph)
for Word in string.gmatch(Paragraph, "[^ ]+") do
print ("Word=", Word)
end
end
但这有一个不同的问题:
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=
空白行出现两次!
一个方便的函数,用于迭代字符串,一次一行,是这样的:
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
处理空行。现在您可以像这样编写代码(假设上面的函数在代码之前):
for Paragraph in getlines (code) do
print("Line=", Paragraph)
for Word in string.gmatch(Paragraph, "[^ ]+") do
print ("Word=", Word)
end
end
输出:
Line= local a = 1
Word= local
Word= a
Word= =
Word= 1
Line=
Line= local b = 2
Word= local
Word= b
Word= =
Word= 2
Line=
您可以将函数getlines
转换为Lua模块,如下所示:
<强> getlines.lua 强>
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
return getlines
现在你所要做的就是&#34;要求&#34;它:
require "getlines"
for Paragraph in getlines (code) do
print("Line=", Paragraph)
for Word in string.gmatch(Paragraph, "[^ ]+") do
print ("Word=", Word)
end
end
答案 2 :(得分:0)
这应该可以解决问题:
local y,code = 0,[[
local a = 123
local b = 456
local c = "too much newlines because we're cool"
]]
local i = 1
-- Why would you start with newlines? Oh well
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
它为您提供了这个不错的输出:
PARAGRAPH: local a = 123
PARAGRAPH: local b = 456
PARAGRAPH: local c = "too much newlines because we're cool"
进行测试