web-dev-qa-db-fra.com

Comment diviser une chaîne de plusieurs lignes en plusieurs lignes?

J'ai un littéral de chaîne multiligne que je veux faire une opération sur chaque ligne, comme ceci:

inputString = """Line 1
Line 2
Line 3"""

Je veux faire quelque chose comme ce qui suit:

for line in inputString:
    doStuff()
255
bradtgmurray
inputString.splitlines()

Vous donnera une liste avec chaque élément. La méthode splitlines() est conçue pour scinder chaque ligne en un élément de la liste.

385
UnkwnTech

Comme les autres ont dit:

inputString.split('\n')  # --> ['Line 1', 'Line 2', 'Line 3']

Ceci est identique à ce qui précède, mais les fonctions du module de chaîne sont obsolètes et doivent être évitées:

import string
string.split(inputString, '\n')  # --> ['Line 1', 'Line 2', 'Line 3']

Si vous souhaitez que chaque ligne comprenne la séquence d'interruption (CR, LF, CRLF), utilisez la méthode splitlines avec un argument True:

inputString.splitlines(True)  # --> ['Line 1\n', 'Line 2\n', 'Line 3']
196
efotinis

Utilisez str.splitlines().

splitlines() gère correctement les nouvelles lignes, contrairement à split("\n").

Il présente également l’avantage mentionné par @efotinis d’inclure éventuellement le caractère de nouvelle ligne dans le résultat du fractionnement lorsqu’il est appelé avec un argument True.


Explication détaillée sur les raisons pour lesquelles vous ne devriez pas utiliser split("\n"):

\n, en Python, représente un saut de ligne Unix (code décimal ASCII 10), indépendamment de la plate-forme sur laquelle vous l'exécutez. Cependant, la représentation de saut de ligne dépend de la plate-forme . Sous Windows, \n est constitué de deux caractères, CR et LF (codes décimaux ASCII 13 et 10, AKA \r et \n), tandis que sous Unix moderne (y compris OS X), c’est le caractère unique LF.

print, par exemple, fonctionne correctement même si vous avez une chaîne avec des fins de ligne qui ne correspondent pas à votre plate-forme:

>>> print " a \n b \r\n c "
 a 
 b 
 c

Cependant, une scission explicite sur "\ n" donnera un comportement dépendant de la plate-forme:

>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']

Même si vous utilisez os.linesep, il ne sera divisé qu'en fonction du séparateur de nouvelle ligne de votre plate-forme et échouera si vous traitez du texte créé sur d'autres plates-formes ou avec un \n:

>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']

splitlines résout tous ces problèmes:

>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']

Lire des fichiers en mode texte atténue partiellement le problème de représentation de la nouvelle ligne, car il convertit le \n de Python en représentation de nouvelle ligne de la plate-forme. Cependant, le mode texte n'existe que sous Windows. Sur les systèmes Unix, tous les fichiers sont ouverts en mode binaire. Par conséquent, l'utilisation de split('\n') dans un système UNIX avec un fichier Windows entraînera un comportement indésirable. De plus, il n'est pas inhabituel de traiter des chaînes avec des passages à la ligne potentiellement différents d'autres sources, telles que celles provenant d'un socket.

46
goncalopp

Peut-être excessif dans ce cas particulier, mais une autre option implique l'utilisation de StringIO pour créer un objet de type fichier

for line in StringIO.StringIO(inputString):
    doStuff()
19
iruvar

La publication d'origine demandée pour le code qui imprime certaines lignes (si elles sont vraies pour certaines conditions) plus la ligne suivante. Ma mise en œuvre serait la suivante:

text = """1 sfasdf
asdfasdf
2 sfasdf
asdfgadfg
1 asfasdf
sdfasdgf
"""

text = text.splitlines()
rows_to_print = {}

for line in range(len(text)):
    if text[line][0] == '1':
        rows_to_print = rows_to_print | {line, line + 1}

rows_to_print = sorted(list(rows_to_print))

for i in rows_to_print:
    print(text[i])
1
Finrod Felagund

Je souhaite que les commentaires aient un format de texte de code approprié, car je pense que la réponse de @ 1_CR a besoin de plus de bosses, et je voudrais augmenter sa réponse. En tout cas, il m'a conduit à la technique suivante; il utilisera cStringIO s'il est disponible (MAIS NOTE: cStringIO et StringIO sont pas identiques, car vous ne pouvez pas sous-classe cStringIO ... c'est une commande intégrée ... mais pour les opérations de base, la syntaxe sera identique, vous pouvez donc le faire):

try:
    import cStringIO
    StringIO = cStringIO
except ImportError:
    import StringIO

for line in StringIO.StringIO(variable_with_multiline_string):
    pass
print line.strip()
1
Mike S