#lua #world-of-warcraft
#lua #world-of-warcraft
Вопрос:
Я использую Lua в World of Warcraft.
У меня есть эта строка:
"Thisnisnmynlife."
Итак, при печати выводится следующее:
This
is
my
life.
Как я могу сохранить всю строку, кроме последней строки, в новой переменной?
Итак, я хочу, чтобы вывод новой переменной был таким:
This
is
my
Я хочу, чтобы код Lua находил последнюю строку (независимо от того, сколько строк в строке), удалял последнюю строку и сохранял оставшиеся строки в новой переменной.
Спасибо.
Комментарии:
1.
new_str = old_str:gsub("n[^n]*$", "")
2. Это здорово, Егор. Можете ли вы сказать мне, как сохранить первую строку old_str в new_str тоже?
3.
first_line = old_str:match("[^n]*")
4. Спасибо, Егор. Я хотел бы отметить это как правильный ответ, но я не могу отметить комментарий. Если вы хотите поместить свои ответы в ответ, я отмечу его как правильный.
5.
new_str = old_str:gsub("n[^n]*(n?)$", "%1")
решит проблему, описанную @exnihilo
Ответ №1:
Итак, я обнаружил, что решения Егора Скриптунова в комментариях действительно работали очень хорошо, но я не могу пометить его комментарии как ответ, поэтому я помещу его ответы здесь.
При этом удаляется последняя строка, а оставшиеся строки сохраняются в новой переменной:
new_str = old_str:gsub("n[^n]*$", "")
Если в конце последней строки есть маркер новой строки, Егор опубликовал это как решение:
new_str = old_str:gsub("n[^n]*(n?)$", "%1")
При этом первая строка удаляется, а остальные строки сохраняются в новой переменной:
first_line = old_str:match("[^n]*")
Спасибо за помощь, Егор.
Ответ №2:
Наиболее эффективным решением является обычная string.find.
local s = "Thisnisnmynlife." -- 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
символами новой строки, если у вас есть nr
, или rn
более простым решением будет шаблон.
Это решение эффективно для LuaJIT и для длинных строк. Для маленьких строк string.sub(s1, 1, string.find(s1,"n[^n]*$") - 1)
это нормально (не на LuaJIT tho).
Ответ №3:
Я сканирую ее назад, потому что проще удалить что-то из back с помощью обратного сканирования, а не вперед, было бы сложнее, если бы вы сканировали вперед и намного проще сканировали назад
Я преуспеваю в этом за один дубль
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("Thisnisnmynlife.")
print(removeLastLine("Thisnisnmynlife."))
Как работает код
-
Буквы в
str
аргументе будут извлечены в таблицу ("Hello"
станут{"H", "e", "l", "l", "o"}
) -
i
local устанавливается в конец таблицы, потому что мы просматриваем ее от начала до конца -
Проверьте, есть ли
letters[i]
n, если это новая строка, затем перейдите к шагу 7 -
Удалить запись в
letters[i]
-
Минус
i
с 1 -
Переходим к шагу 3, пока
i
не будет равно нулю, еслиi
равно нулю, то переходим к шагу 8 -
Удалить запись в
letters[i]
, потому что она не удалялась при проверке новой строки -
Возврат
table.concat(letters)
. Не вызовет ошибки, потомуtable.concat
что возвращает пустую строку, если таблица пуста
Ответ №4:
#! /usr/bin/env lua
local serif = "Is this thenreal life?nIs thisnjust 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 thenreal life?nIs thisnjust fantasy?"
print( str :sub( 1, -str :reverse() :find( 'n' ) -1 ) )
Is this the
real life?
Is this
Комментарии:
1. Не понижающий параметр, но это не удается для входных строк, которые не содержат символов новой строки.