如何从 Lua 中的字符串中删除最后一行?
How to remove last line from a string in Lua?
我在玩魔兽世界Lua
我有这个字符串:
"This\nis\nmy\nlife."
所以当打印时,输出是这样的:
This
is
my
life.
如何将除最后一行之外的整个字符串存储在新变量中?
所以我希望新变量的输出是这样的:
This
is
my
我希望 Lua 代码找到最后一行(不管字符串中有多少行),删除最后一行并将剩余行存储在新变量中。
谢谢。
#! /usr/bin/env lua
local serif = "Is this the\nreal life?\nIs this\njust fantasy?"
local reversed = serif :reverse() -- flip it
local pos = reversed :find( '\n' ) +1 -- count backwards
local sans_serif = serif :sub( 1, -pos ) -- strip it
print( sans_serif )
如果你愿意,你可以联机,结果相同。
local str = "Is this the\nreal life?\nIs this\njust fantasy?"
print( str :sub( 1, -str :reverse() :find( '\n' ) -1 ) )
Is this the
real life?
Is this
最有效的解决方案是简单的 string.find。
local s = "This\nis\nmy\nlife." -- string with newlines
local s1 = "Thisismylife." -- string without newlines
local function RemoveLastLine(str)
local pos = 0 -- start position
while true do -- loop for searching newlines
local nl = string.find(str, "\n", pos, true) -- find next newline, true indicates we use plain search, this speeds up on LuaJIT.
if not nl then break end -- We didn't find any newline or no newlines left.
pos = nl + 1 -- Save newline position, + 1 is necessary to avoid infinite loop of scanning the same newline, so we search for newlines __after__ this character
end
if pos == 0 then return str end -- If didn't find any newline, return original string
return string.sub(str, 1, pos - 2) -- Return substring from the beginning of the string up to last newline (- 2 returns new string without the last newline itself
end
print(RemoveLastLine(s))
print(RemoveLastLine(s1))
请记住,这仅适用于具有 \n
样式换行符的字符串,如果您有 \n\r
或 \r\n
更简单的解决方案是模式。
此解决方案对于 LuaJIT 和长字符串非常有效。
对于小字符串 string.sub(s1, 1, string.find(s1,"\n[^\n]*$") - 1)
很好(不是在 LuaJIT 上)。
所以我发现 Egor Skriptunoff 在评论中的解决方案确实非常有效,但我无法将他的评论标记为答案,所以我将他的答案放在这里。
这将删除最后一行并将剩余行存储在新变量中:
new_str = old_str:gsub("\n[^\n]*$", "")
如果在最后一行的末尾有一个新的行标记,Egor 发布了这个作为解决方案:
new_str = old_str:gsub("\n[^\n]*(\n?)$", "%1")
虽然这会删除第一行并将其余行存储在新变量中:
first_line = old_str:match("[^\n]*")
谢谢你的帮助,Egor。
我向后扫描它是因为向后扫描比向前扫描更容易从后面移除东西如果向前扫描会更复杂而向后扫描更简单
我一次成功
function removeLastLine(str) --It will return empty string when there just 1 line
local letters = {}
for let in string.gmatch(str, ".") do --Extract letter by letter to a table
table.insert(letters, let)
end
local i = #letters --We're scanning backward
while i >= 0 do --Scan from bacward
if letters[i] == "\n" then
letters[i] = nil
break
end
letters[i] = nil --Remove letter from letters table
i = i - 1
end
return table.concat(letters)
end
print("This\nis\nmy\nlife.")
print(removeLastLine("This\nis\nmy\nlife."))
代码的工作原理
str
参数中的字母将被提取到table("Hello"
将变为{"H", "e", "l", "l", "o"}
)
i
local设置为table的末尾,因为我们是从后往前扫描的
检查 letters[i]
是否为 \n 如果换行则转到步骤 7
删除 letters[i]
处的条目
减去i
与1
转到第 3 步,直到 i
为零如果 i
为零,则转到第 8 步
删除 letters[i]
处的条目,因为它在检查换行符时尚未删除
Returntable.concat(letters)
。不会导致错误,因为如果 table 为空
table.concat
return 空字符串
我在玩魔兽世界Lua
我有这个字符串:
"This\nis\nmy\nlife."
所以当打印时,输出是这样的:
This
is
my
life.
如何将除最后一行之外的整个字符串存储在新变量中?
所以我希望新变量的输出是这样的:
This
is
my
我希望 Lua 代码找到最后一行(不管字符串中有多少行),删除最后一行并将剩余行存储在新变量中。
谢谢。
#! /usr/bin/env lua
local serif = "Is this the\nreal life?\nIs this\njust fantasy?"
local reversed = serif :reverse() -- flip it
local pos = reversed :find( '\n' ) +1 -- count backwards
local sans_serif = serif :sub( 1, -pos ) -- strip it
print( sans_serif )
如果你愿意,你可以联机,结果相同。
local str = "Is this the\nreal life?\nIs this\njust fantasy?"
print( str :sub( 1, -str :reverse() :find( '\n' ) -1 ) )
Is this the
real life?
Is this
最有效的解决方案是简单的 string.find。
local s = "This\nis\nmy\nlife." -- string with newlines
local s1 = "Thisismylife." -- string without newlines
local function RemoveLastLine(str)
local pos = 0 -- start position
while true do -- loop for searching newlines
local nl = string.find(str, "\n", pos, true) -- find next newline, true indicates we use plain search, this speeds up on LuaJIT.
if not nl then break end -- We didn't find any newline or no newlines left.
pos = nl + 1 -- Save newline position, + 1 is necessary to avoid infinite loop of scanning the same newline, so we search for newlines __after__ this character
end
if pos == 0 then return str end -- If didn't find any newline, return original string
return string.sub(str, 1, pos - 2) -- Return substring from the beginning of the string up to last newline (- 2 returns new string without the last newline itself
end
print(RemoveLastLine(s))
print(RemoveLastLine(s1))
请记住,这仅适用于具有 \n
样式换行符的字符串,如果您有 \n\r
或 \r\n
更简单的解决方案是模式。
此解决方案对于 LuaJIT 和长字符串非常有效。
对于小字符串 string.sub(s1, 1, string.find(s1,"\n[^\n]*$") - 1)
很好(不是在 LuaJIT 上)。
所以我发现 Egor Skriptunoff 在评论中的解决方案确实非常有效,但我无法将他的评论标记为答案,所以我将他的答案放在这里。
这将删除最后一行并将剩余行存储在新变量中:
new_str = old_str:gsub("\n[^\n]*$", "")
如果在最后一行的末尾有一个新的行标记,Egor 发布了这个作为解决方案:
new_str = old_str:gsub("\n[^\n]*(\n?)$", "%1")
虽然这会删除第一行并将其余行存储在新变量中:
first_line = old_str:match("[^\n]*")
谢谢你的帮助,Egor。
我向后扫描它是因为向后扫描比向前扫描更容易从后面移除东西如果向前扫描会更复杂而向后扫描更简单
我一次成功
function removeLastLine(str) --It will return empty string when there just 1 line
local letters = {}
for let in string.gmatch(str, ".") do --Extract letter by letter to a table
table.insert(letters, let)
end
local i = #letters --We're scanning backward
while i >= 0 do --Scan from bacward
if letters[i] == "\n" then
letters[i] = nil
break
end
letters[i] = nil --Remove letter from letters table
i = i - 1
end
return table.concat(letters)
end
print("This\nis\nmy\nlife.")
print(removeLastLine("This\nis\nmy\nlife."))
代码的工作原理
str
参数中的字母将被提取到table("Hello"
将变为{"H", "e", "l", "l", "o"}
)i
local设置为table的末尾,因为我们是从后往前扫描的检查
letters[i]
是否为 \n 如果换行则转到步骤 7删除
处的条目letters[i]
减去
i
与1转到第 3 步,直到
i
为零如果i
为零,则转到第 8 步删除
letters[i]
处的条目,因为它在检查换行符时尚未删除Return
table.concat(letters)
。不会导致错误,因为如果 table 为空table.concat
return 空字符串