2
votes

Comment supprimer la dernière ligne d'une chaîne en Lua?

J'utilise Lua dans World of Warcraft.

J'ai cette chaîne:

This
is
my

Ainsi, une fois imprimée, la sortie est la suivante:

This
is
my
life.

Comment puis-je stocker la chaîne entière sauf la dernière ligne dans une nouvelle variable?

Je veux donc que la sortie de la nouvelle variable soit la suivante:

"This\nis\nmy\nlife."

Je veux que le code Lua trouve la dernière ligne (quel que soit le nombre de lignes dans la chaîne), supprime la dernière ligne et stocke les lignes restantes dans une nouvelle variable.

Merci.


7 commentaires

new_str = old_str:gsub("\n[^\n]*$", "")


C'est génial Egor. Pouvez-vous me dire comment stocker la première ligne de old_str dans new_str aussi?


first_line = old_str:match("[^\n]*")


Merci, Egor. Je voudrais marquer ceci comme une réponse correcte mais je ne peux pas marquer un commentaire. Si vous souhaitez mettre vos réponses dans une réponse, je la marquerai comme correcte.


Par convention, une ligne se termine toujours par un caractère de nouvelle ligne, de sorte que la chaîne d'exemple n'a pas vraiment de dernière ligne à supprimer. L'approche @EgorSkriptunoff est excellente pour l'exemple, mais selon la façon dont la chaîne d'entrée est créée, vous pouvez avoir "This\nis\nmy\nlife.\n" , où il y a vraiment une ligne à la fin de la chaîne; alors des ajustements seraient nécessaires. Voulez-vous vraiment supprimer les caractères suivant le dernier saut de ligne de la chaîne ou souhaitez-vous supprimer la dernière ligne de la chaîne?


Vous n'avez pas spécifié si toutes les chaînes contiennent une nouvelle ligne ou si vous avez besoin de ce test inclus. De plus, vous n'avez montré aucune tentative.


new_str = old_str:gsub("\n[^\n]*(\n?)$", "%1") résoudra le problème décrit par @exnihilo


3 Réponses :


-4
votes
local str = "Is this the\nreal life?\nIs this\njust fantasy?"
print(  str :sub( 1,  -str :reverse() :find( '\n' ) -1 )  )

1 commentaires

Il ne s'agit pas d'un vote négatif, mais cela échoue pour les chaînes d'entrée qui ne contiennent aucun caractère de nouvelle ligne.



0
votes

La solution la plus efficace est 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))

Gardez à l'esprit que cela ne fonctionne que pour les chaînes avec des sauts de ligne de style \n , si vous avez \n\r ou \r\n une solution plus simple serait un modèle.

Cette solution est efficace pour LuaJIT et pour les longues chaînes. Pour les petites chaînes string.sub(s1, 1, string.find(s1,"\n[^\n]*$") - 1) convient (pas sur LuaJIT tho).


0 commentaires

0
votes

J'ai donc trouvé que les solutions d'Egor Skriptunoff dans les commentaires fonctionnaient très bien, mais je suis incapable de marquer ses commentaires comme une réponse, je vais donc mettre ses réponses ici.

Cela supprime la dernière ligne et stocke les lignes restantes dans une nouvelle variable:

first_line = old_str:match("[^\n]*")

S'il y a un nouveau marqueur de ligne à la fin de la dernière ligne, Egor a posté ceci comme solution:

new_str = old_str:gsub("\n[^\n]*(\n?)$", "%1")

Bien que cela supprime la première ligne et stocke les lignes restantes dans une nouvelle variable:

new_str = old_str:gsub("\n[^\n]*$", "")

Merci pour votre aide, Egor.


0 commentaires