Aller au contenu
Allin

Nettoyer une liste collée depuis un tableur ou un PDF

Publié le 06/08/2026 · 13 min de lecture · Outils texte & langage

Daniel Okonkwo

Daniel OkonkwoDéveloppeur front-end et rédacteur Tech chez Allin

Performance web · Formats de fichiers

Vérifié à partir de 4 sources

Voir le profil
En bref

Passe d'abord trim-lines, puis remove-blank-lines. L'ordre compte parce que remove-blank-lines décide de ce qui est vide avec le .trim() de JavaScript, qui traite bien U+00A0 (espace insécable) comme un espace, mais ne touche pas au texte des lignes qu'il garde — une ligne « Lyon » survit donc avec ses trois espaces finaux. trim-lines utilise le même .trim() et nettoie les deux bouts de chaque ligne, y compris un retour chariot isolé. À eux deux ils traitent espaces, tabulations, espaces insécables, espaces fines et marque d'ordre des octets. Deux caractères leur échappent : U+00AD, le trait d'union conditionnel qu'un PDF insère là où il a coupé un mot en fin de ligne, et U+200B, l'espace de largeur nulle. Aucun des deux n'est un espace pour JavaScript : ils traversent remove-blank-lines, trim-lines, trailing-whitespace-remover et remove-whitespace sans être modifiés. Surveille surtout trailing-whitespace-remover : il ne reconnaît que l'espace ASCII et la tabulation, si bien que sur la chaîne « x » suivie d'une espace insécable il ne change rien, et sur « x » + insécable + espace ordinaire il retire l'espace ordinaire et laisse l'insécable. Les quatre outils réécrivent aussi silencieusement les fins de ligne CRLF en simples sauts de ligne, ce qui est en général souhaité, et aucun ne considère un retour chariot isolé comme un saut de ligne. Un collage depuis un tableur apporte en plus des tabulations entre les cellules d'une ligne — remove-whitespace avec ses réglages par défaut supprimera ces tabulations et collera tes colonnes les unes aux autres.

Un collage transporte des caractères invisibles : espaces insécables, traits d'union conditionnels, espaces de largeur nulle, tabulations et CRLF. Quatre outils de nettoyage ont été passés sur chacun, et ils utilisent trois définitions différentes de l'espace.

Ce qui arrive vraiment dans le presse-papiers

Le texte affiché à l'écran et le texte du presse-papiers ne sont pas le même objet. Un PDF n'a ni lignes ni paragraphes : il a des boîtes de glyphes à des coordonnées. Quand tu sélectionnes une colonne de texte et que tu la copies, le lecteur reconstruit un ordre de lecture plausible et insère un saut de ligne à la fin de chaque boîte — une phrase qui courait sur trois lignes imprimées arrive donc en trois lignes. Si le compositeur a coupé un mot à l'une de ces fins de ligne, certains producteurs écrivent un vrai trait d'union et d'autres U+00AD, le trait d'union conditionnel, qui ne s'affiche comme un tiret que si une coupure tombe là, et sinon comme rien du tout. Et comme la plupart des PDF européens sont composés avec des espaces insécables avant les deux-points, les points-virgules et les unités, un document français ou italien te tend des U+00A0 là où tu jurerais qu'il y a des espaces ordinaires.

Un collage depuis un tableur est plus propre, mais pas propre. Excel, Numbers et Google Sheets mettent tous une tabulation entre les cellules d'une ligne et un saut de ligne entre les lignes, et sous Windows ce saut de ligne est un CRLF — un retour chariot suivi d'un saut de ligne, deux caractères là où tu en vois un. Supprime un bloc de lignes au milieu d'une sélection et tu copies souvent aussi les lignes vides, qui arrivent sous forme de lignes ne contenant que des tabulations. C'est exactement la forme pour laquelle les outils de cette page sont faits : une liste où les lignes utiles sont séparées par des lignes ne contenant que des caractères invisibles, et où certaines lignes utiles portent elles-mêmes des caractères invisibles à un bout ou aux deux.

Quatre outils, trois définitions de l'espace

remove-blank-lines et trim-lines appellent tous deux le .trim() de JavaScript. Le langage définit ce qu'il supprime comme WhiteSpace plus LineTerminator, et WhiteSpace inclut tous les caractères de la catégorie Unicode Space_Separator — d'où relèvent U+00A0, U+2009 (espace fine) et U+202F (espace fine insécable) — ainsi que la marque d'ordre des octets U+FEFF. Passe chacun de ces caractères seul sur une ligne dans remove-blank-lines et la ligne disparaît. remove-whitespace utilise la classe d'expression régulière \s, qui désigne le même ensemble. Trois des quatre outils s'accordent donc sur l'espace insécable, et s'accordent avec ce qu'un lecteur attendrait.

trailing-whitespace-remover, non. Son motif est une suite d'espaces ASCII ou de tabulations ancrée en fin de ligne, et rien d'autre ne compte. Nourri de la chaîne x suivie d'une espace insécable, il rend la chaîne inchangée. Nourri de x suivi d'une insécable puis d'une espace ordinaire, il retire l'espace ordinaire et rend x plus l'insécable — visuellement pas plus court d'un poil, et toujours différent de x. Ce n'est pas une différence cosmétique. Si tu nettoies une liste avant de la dédoublonner, c'est cette insécable survivante qui maintient deux noms de ville identiques séparés.

Les deux caractères qu'aucun de ces outils ne supprime

U+00AD, le trait d'union conditionnel, et U+200B, l'espace de largeur nulle, ne sont pas des espaces pour JavaScript. La classe d'expression régulière \s ne les reconnaît pas et .trim() ne les supprime pas, ce qui a été vérifié directement plutôt que supposé. Une ligne ne contenant qu'un trait d'union conditionnel survit donc à remove-blank-lines et ressemble, dans la zone de sortie, exactement à une ligne vide que l'outil aurait refusé de supprimer. Le mot « coopératives » copié depuis un PDF avec césure, avec un trait d'union conditionnel entre « co » et « opératives », ressort identique des quatre outils — et ne correspondra jamais à la chaîne « coopératives » dans aucune recherche que tu feras ensuite.

Un seul outil de ce site les supprime réellement, et le marché est mauvais pour cinq de nos six langues. remove-non-ascii retire tout caractère au-dessus de U+007F, ce qui emporte bien le trait d'union conditionnel, l'espace de largeur nulle, l'espace insécable et la marque d'ordre des octets. Il emporte aussi purement et simplement chaque lettre accentuée au lieu de la replier : la phrase « Les coopératives régionales », passée avec un trait d'union conditionnel dans le premier mot, est ressortie « Les coopratives rgionales » — le é disparu, pas remplacé par un e. La voie honnête est find-and-replace avec le caractère fautif collé dans le champ « Rechercher », qui fonctionne parce que cet outil échappe son terme de recherche et le compare littéralement. Encore faut-il se procurer un exemplaire d'un caractère invisible, ce qui est exactement aussi pénible que ça en a l'air.

Fins de ligne, et le seul saut que ces outils ne voient pas

Les quatre outils découpent sur un saut de ligne précédé d'un retour chariot facultatif, puis rejoignent le résultat avec de simples sauts de ligne. Chacun d'eux normalise donc les fins de ligne CRLF de Windows en sauts de ligne Unix, en plus de ce que tu lui as demandé : colle un bloc de tableur, passe remove-blank-lines, et la sortie est plus courte d'un octet par ligne même si aucune ligne n'a été supprimée. C'est presque toujours ce que tu voulais, mais il vaut la peine de savoir que c'est arrivé, car un fichier qui doit repartir vers un outil Windows demandera peut-être qu'on lui rende ses fins de ligne.

Le saut qu'ils ne voient pas est un retour chariot isolé, sans saut de ligne derrière — la fin de ligne du Mac OS classique jusqu'en 2001, et celle que quelques vieilles routines d'export et certains dumps de bases émettent encore. Devant les trois caractères a, retour chariot, retour chariot, b, les quatre outils traitent l'ensemble comme une seule ligne et la rendent intacte. Rien ne t'avertit. Si un collage revient sous forme d'une immense ligne unique sans saut visible et sans erreur, c'est la première chose à soupçonner, et le remède est d'ouvrir le fichier dans un éditeur capable de convertir les fins de ligne avant de l'amener ici.

L'ordre dans lequel les enchaîner

trim-lines d'abord, remove-blank-lines ensuite. L'ordre inverse donne le même résultat sur la plupart des entrées, parce que remove-blank-lines teste déjà chaque ligne avec .trim() avant de décider — une ligne de trois espaces saute que tu aies rogné avant ou non. Vérifié sur l'entrée bancale « deux espaces, alpha, deux espaces », puis une ligne de tabulation seule, puis « deux espaces, beta, un espace », puis une ligne vide, puis « alpha » : les deux ordres ont produit alpha, beta, alpha. La raison de mettre quand même trim-lines en premier, c'est la suite. Donne cette même entrée à duplicate-line-finder sans l'avoir rognée et il ne signale aucun doublon, parce que le premier alpha porte deux espaces devant et deux derrière. Donne-lui la version rognée et il signale alpha.

Deux choses à éviter. Ne sors pas remove-whitespace sur un collage de tableur si tu n'as pas décidé que les colonnes pouvaient disparaître : avec son réglage par défaut il supprime chaque espace, tabulation et saut de ligne, et la ligne d'en-tête « Nom, tabulation, Ville, tabulation, CA » est ressortie « NomVilleCA ». Activer « garder les sauts de ligne » préserve les lignes mais mange toujours les tabulations, donc les colonnes restent collées. Et ne passe pas trailing-whitespace-remover en espérant qu'il rende deux lignes comparables : il retire l'espace ASCII et la tabulation, et rien d'autre, ce qui était tout l'objet de la deuxième section. Quand l'objectif est la comparaison plutôt que la propreté, c'est trim-lines qui referme l'écart.

Une ligne d'entrée, passée dans chacun des quatre outils, avec la sortie réellement produite
EntréeCe qui se passePourquoi
Une ligne de trois espaces ordinaires, dans remove-blank-linesSuppriméeLe test est ligne.trim().length > 0, et .trim() la vide
Une ligne ne contenant qu'un U+00A0, dans remove-blank-linesSuppriméeLe WhiteSpace d'ECMAScript couvre toute la catégorie Space_Separator
Une ligne ne contenant qu'un U+00AD, dans remove-blank-linesConservée, et paraît vide dans la sortieLe trait d'union conditionnel est de catégorie Cf, un caractère de formatage, pas un espace
x suivi d'un U+00A0, dans trailing-whitespace-removerRendu inchangéSon motif est une suite d'espaces ASCII ou de tabulations en fin de ligne, rien de plus large
x, puis U+00A0, puis une espace ordinaire, dans trailing-whitespace-removerRevient sous la forme x suivi d'un U+00A0La suite d'espaces ASCII s'arrête au premier caractère hors de la classe
Le même x plus U+00A0, dans trim-linesRevient sous la forme xLe même .trim() que remove-blank-lines, appliqué au texte au lieu du test
La ligne d'en-tête Nom, tabulation, Ville, tabulation, CA, dans remove-whitespaceNomVilleCA — les colonnes ont disparuUne tabulation est un espace, et « garder les sauts de ligne » n'épargne que le saut de ligne
a, retour chariot, retour chariot, b — dans n'importe lequel des quatreTraité comme une seule ligne, rendu intactIls découpent tous sur un saut de ligne précédé d'un retour chariot facultatif
Supprimer les lignes videsSupprime toutes les lignes vides ou ne contenant que des espaces.Essayer l'outil

Questions fréquentes

Pourquoi ma liste garde-t-elle des lignes d'apparence vide après remove-blank-lines ?
C'est presque à coup sûr une espace de largeur nulle (U+200B) ou un trait d'union conditionnel (U+00AD) seul sur la ligne. Ni l'un ni l'autre n'est un espace pour JavaScript : le test de l'outil — reste-t-il quelque chose après .trim() — répond oui, et la ligne demeure. Les deux ont été passés dans l'outil pour le confirmer. Une espace insécable ou une espace fine seule aurait été supprimée, la ligne survivante n'est donc pas de celles-là. Pour identifier le caractère sans deviner, colle la ligne dans un compteur de caractères ou d'octets et constate que le compte vaut un et non zéro.
trailing-whitespace-remover est-il donc cassé ?
Il fait ce que sa propre description annonce — supprimer les espaces et tabulations en fin de ligne — et cette définition étroite est la bonne pour son usage habituel : nettoyer les résidus invisibles en fin de lignes de code avant un commit. Les outils de diff et les linters s'occupent de l'espace ASCII et de la tabulation ; une espace insécable dans du code est un bogue que tu veux voir, pas un que tu veux voir disparaître en silence. Le seul problème est que le nom se lit comme une promesse générale. Pour de la prose et pour des listes collées depuis des documents, c'est trim-lines qui a la définition large, et c'est lui qu'il faut employer quand deux lignes doivent ensuite se comparer comme égales.
Comment me débarrasser des traits d'union conditionnels qu'un PDF a mis dans mon texte ?
Aucun des quatre outils de cet article ne le fera. find-and-replace le fera, si tu parviens à mettre un trait d'union conditionnel dans son champ « Rechercher » : l'outil échappe ce que tu tapes et le compare littéralement, ce qui a été vérifié, donc coller le caractère fonctionne et taper sa description non. Se procurer un exemplaire d'un caractère invisible passe en général par sélectionner un espace suspicieusement large dans le texte source avec les flèches et Maj, puis le copier. remove-non-ascii les supprime aussi, mais il emporte avec eux chaque lettre accentuée sans la remplacer : sur du texte français, espagnol, portugais, allemand ou italien, il détruit plus qu'il ne répare.
Est-ce que tout cela envoie ma liste à un serveur ?
Non. Les quatre transformations sont de simples opérations sur des chaînes qui s'exécutent dans la page ouverte, sur le texte de la zone de saisie, et produisent leur sortie dans la même page. Rien dans la nature du travail n'exige un serveur : découper sur les sauts de ligne et tester chaque ligne tient en quelques lignes de code, et il n'y a ni dictionnaire ni modèle à consulter. Cela compte davantage que d'habitude ici, car les listes qu'on nettoie ainsi viennent souvent de documents internes — noms de clients, références de commandes, effectifs — et en coller une dans un outil qui l'envoie est une décision de transfert de données, pas une décision de mise en forme.
Mon collage de tableur garde ses tabulations. Comment obtenir un élément par ligne ?
Aucun des quatre ne fait cela, et remove-whitespace fait même l'inverse : il supprime les tabulations et soude les cellules entre elles, ce qui a été vérifié sur une ligne d'en-tête de trois colonnes revenue en un seul mot. Si tu ne voulais qu'une colonne, copie une seule colonne depuis le tableur : le collage ne contient alors aucune tabulation et remove-blank-lines plus trim-lines suffisent. Si tu as plusieurs colonnes et que tu veux les empiler une par ligne, c'est une autre opération avec son propre outil, et la réponse honnête est que ces quatre-là nettoient des lignes, ils ne découpent pas des colonnes.

Articles qui pourraient t'intéresser

Tous les guides
ExplicationTrouver les doublons d'une liste sans tableurDeux lignes qui paraissent identiques ne le sont souvent pas. La casse, une espace finale, une espace insécable et deux encodages différents de la même lettre accentuée ont été passés dans le détecteur de doublons : il n'en a signalé aucun dans trois cas sur quatre.TutorielFiltrer des lignes selon un motif, sans ligne de commandeC'est grep pour ceux qui n'utilisent pas grep, avec une différence de taille : la recherche est une sous-chaîne littérale, si bien qu'une vraie expression régulière renvoie une zone vide sans message d'erreur. Chaque affirmation a été vérifiée en exécutant l'outil.TutorielNettoyer un texte en désordre : l'ordre des opérations qui compte vraimentRetirer les balises avant de décoder les entités, couper les espaces avant de dédupliquer, écraser les blancs en dernier. Trois ordres exécutés dans Node, un pipeline de neuf étapes dans le bon sens, et les caractères invisibles — U+00A0, U+200B, U+FEFF — qui survivent à tout nettoyage naïf.GuideConvertir entre formats de liste sans perdre de données : les règles de guillemets que personne ne litPasser d'une liste à retours à la ligne à une liste à virgules est trivial jusqu'à ce qu'un élément contienne une virgule. Les règles de guillemets de la RFC 4180, pourquoi un champ CSV peut contenir un saut de ligne, pourquoi les tableurs européens utilisent le point-virgule, et ce qu'un élément vide fait à l'aller-retour — chaque cas exécuté et imprimé.ExplicationDétecter la langue d'un texte, et pourquoi les textes courts échouentMesuré, pas affirmé : 90 phrases courtes réelles dans six langues, aucune refusée et 68 justes — 76 %, tombant à 64 % en dessous de seize lettres. Quatre des réponses fausses sont revenues avec 100 % de confiance.TutorielNuméroter les lignes d'un texte pour une relecture à plusieursLa numérotation commence à 1 et ne peut pas être mise à 0, l'alignement se fait avec des espaces et non des zéros, et l'outil de suppression annule huit des onze séparateurs sans toucher à l'indentation. Ce qu'il ne sait toujours pas faire, c'est distinguer tes numéros des siens.

Outils similaires

Tout ce qui suit décrit ce que font ces outils aujourd'hui, vérifié en exécutant leurs propres transformations sur les entrées exactes reproduites dans chaque article, et non ce qu'une norme imposerait à un outil de texte. Le traitement du texte ligne à ligne n'a aucune autorité unique : ce qui compte comme espace, le fait que deux lignes accentuées soient ou non la même ligne, et l'endroit où se termine une URL dans une phrase sont tranchés différemment par chaque programme dans lequel tu colleras du texte. Quand un outil se trompe sur un cas, c'est dit franchement plutôt que contourné. Avant de passer tout cela sur une liste que tu ne pourras pas réexporter, passe sur une copie et compare le nombre de lignes aux deux bouts.

Sources

Tu as repéré une erreur dans cet article ?