Regex pour remplacer plusieurs espaces par un seul espace


511

Étant donné une chaîne comme:

"Le chien a une longue queue, et il est ROUGE!"

Quel type de magie jQuery ou JavaScript peut être utilisé pour limiter les espaces à un seul espace maximum?

Objectif:

"Le chien a une longue queue, et il est ROUGE!"

4
Voulez-vous également faire correspondre les caractères de l'onglet Espace blanc?
Chris Farmer

@Chris, oui s'il vous plaît, grande question .... Avec toutes ces réponses différentes, comment est-on supposé savoir quelle est la solution la plus efficace?
AnApprentice

2
Tout le monde ci-dessous a raison, mais c'est l'expression rationnelle la plus optimisée: str.replace(/ +(?= )/g,'');vous ne remplacez rien de ce que vous n'avez pas à faire.
Evan Carroll

2
Il n'y aura pas de différence notable de performances. Vous pouvez toujours le décrire, mais je doute que cela en vaille la peine. J'irais pour le plus clair.
Draemon

@EvanCarroll: Pas vrai - du moins sur Firefox. Cette version fonctionne beaucoup plus lentement. Voir les résultats du profilage dans ma réponse (ci-dessous).
Edward Loper

Réponses:


937

Étant donné que vous souhaitez également couvrir les onglets, les nouvelles lignes, etc., remplacez simplement \s\s+par ' ':

string = string.replace(/\s\s+/g, ' ');

Si vous voulez vraiment couvrir uniquement les espaces (et donc pas les tabulations, les retours à la ligne, etc.), faites-le:

string = string.replace(/  +/g, ' ');

4
Vous devez également ajouter l'indicateur «g» à l'expression régulière.
Rafael

6
Cela ne fonctionne pas lorsqu'un espace au lieu d'un onglet ou d'une nouvelle ligne est nécessaire. Droite? / \ s + / fonctionnerait.
Fabian

3
il pourrait être préférable pour vous en tant que fonction telle quefunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
Math chiller

5
@Ethan: JS a une fonction pour ce builtin: trim(). C'est plus rapide que regex. Vous pourriez simplement faire string.trim().replace(/\s\s+/g, ' ');ou string.replace(/\s\s+/g, ' ').trim();.
BalusC

4
/\s\s+/get /\s{2,}/gne correspondent pas aux caractères blancs sauf s'il y en a au moins deux adjacents, par exemple correspondra à \ t \ t mais ne correspondra pas à un seul \ t. string.replace(/\s+/g, ' ')correspondra à toutes les sous-chaînes de caractères d'espaces simples et multiples et remplacera par un seul espace.
remyActual

159

Puisque vous semblez être intéressé par les performances, je les ai profilées avec Firebug. Voici les résultats que j'ai obtenus:

str.replace( /  +/g, ' ' )       ->  380ms
str.replace( /\s\s+/g, ' ' )     ->  390ms
str.replace( / {2,}/g, ' ' )     ->  470ms
str.replace( / +/g, ' ' )        ->  790ms
str.replace( / +(?= )/g, ' ')    -> 3250ms

C'est sur Firefox, exécutant des remplacements de chaîne de 100k.

Je vous encourage à faire vos propres tests de profilage avec firebug, si vous pensez que les performances sont un problème. Les humains sont notoirement mal à prédire où se trouvent les goulots d'étranglement dans leurs programmes.

(Notez également que la barre d'outils du développeur d'IE 8 dispose également d'un profileur intégré - il peut être utile de vérifier les performances dans IE.)


5
jsperf.com/removing-multiple-spaces Allez-y et JSPerf! La dernière méthode; ( / +(?= )/g, ' ');échoue dans IE9, il laisse des espaces doubles: "Foo Bar Baz".replace(/ +(?= )/g, ' ');->"Foo Bar Baz"
Nenotlep

comment il y a beaucoup de diff bw 1 et 2nd line
Vivek Panday

@VivekPanday - J'imagine que c'est parce que la deuxième ligne ne remplace que les occurrences d'espaces doubles par un seul espace, tandis que la première remplace également tout espace par un espace. Que ce soit du temps gagné lors de la recherche ou du remplacement réel, je ne sais pas.
Maloric

Cela ne supprime pas les espaces blancs initiaux et finaux. Pour cela, voir cette réponse .
Ethan

Modifié sur commande en diminuant la vitesse. Les commentaires de Vivek et Maloric se réfèrent à des lignes avec 380 ms et 790 ms.
Skippy le Grand Gourou

43
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

EDIT: Si vous souhaitez remplacer toutes sortes de caractères d'espaces, le moyen le plus efficace serait le suivant:

str = str.replace(/\s{2,}/g,' ');

Drôle, votre chaîne de test n'a même pas deux espaces.
Josh Stodola

vient de réaliser que vous aviez déjà ce que j'ai récemment trouvé, +1 :)
meder omuraliev

2
Pour une raison quelconque, cela ne fonctionne pas ... Beaucoup de "& nbsp;" apparaissent ... Probablement à cause de CKEDITOR ...
AnApprentice

K s'avère que le texte de JQUERY () gâchait les choses. fixe - merci à tous!
AnApprentice

16

C'est une solution, mais elle ciblera tous les caractères de l'espace:

"The      dog        has a long tail,      and it is RED!".replace(/\s\s+/g, ' ')

"The dog has a long tail, and it is RED!"

Edit : C'est probablement mieux car il cible un espace suivi de 1 ou plusieurs espaces:

"The      dog        has a long tail,      and it is RED!".replace(/  +/g, ' ')

"The dog has a long tail, and it is RED!"

Méthode alternative:

"The      dog        has a long tail,      and it is RED!".replace(/ {2,}/g, ' ')
"The dog has a long tail, and it is RED!"

Je ne l'ai pas utilisé /\s+/seul car cela remplace les espaces qui s'étendent sur 1 caractère plusieurs fois et pourrait être moins efficace car il cible plus que nécessaire.

Je n'ai testé en profondeur aucun de ceux-ci, alors lmk s'il y a des bugs.

De plus, si vous allez faire un remplacement de chaîne, n'oubliez pas de réaffecter la variable / propriété à son propre remplacement, par exemple:

var string = 'foo'
string = string.replace('foo', '')

Utilisation de jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )

1
Le premier est totalement inutile, \ s \ s + signifie, un \ s suivi d'un ou plusieurs \ s +, qui peut être réduit à un seul \ s +, le deuxième exemple est plus précis parce que nous voulons seulement remplacer les espaces doubles, pas newlines, le troisième est plus optimisé car il ne s'applique qu'aux exemples avec 2+ espaces. Mais str.replace (/ + (? =) / G, '') ;, ne s'applique qu'aux exemples avec 2+ espaces mais économise l'écrasement d'un espace avec un pas d'espace.
Evan Carroll

4
EvanCarroll vous échouez car \ s \ s + est définitivement différent de \ s +. \ s \ s + correspondrait à '\ t \ t' ou '\ t \ t \ t' mais PAS à '\ t'. Et c'est de cela qu'il s'agit, vous ne voulez pas remplacer chaque caractère d'espace blanc f-en.
watain

Je fais. Utilisé pour la recherche en texte intégral (et l'affichage d'extraits): Pas d'onglets aléatoires, de casseurs ou de trucs de choses, s'il vous plaît.
T4NK3R

13

J'ai cette méthode, je l'appelle la méthode Derp faute d'un meilleur nom.

while (str.indexOf("  ") !== -1) {
    str = str.replace(/  /g, " ");
}

L'exécuter dans JSPerf donne des résultats surprenants.


2
Je vais être gêné comme un enfer s'il s'avère que j'ai falsifié le cas de test au lieu qu'il ne soit réellement rapide: D
Nenotlep

Fournir un cas de test ... Excellente réponse!
Oytun

2
Cela a fait ma journée :-) C'est marrant de voir comment le "dérapage" fonctionne souvent mieux que d'être "intelligent". Le "Derp split" semble cependant lui avoir donné un coup de pied. Pourtant, mérite un vote positif.
Fred Gandt

13

Une méthode plus robuste: elle prend également en charge la suppression des espaces initial et final, s'ils existent. Par exemple:

// NOTE the possible initial and trailing spaces
var str = "  The dog      has a long   tail, and it     is RED!  "

str = str.replace(/^\s+|\s+$|\s+(?=\s)/g, "");

// str -> "The dog has a long tail, and it is RED !"

Votre exemple ne comportait pas ces espaces, mais il s'agit également d'un scénario très courant, et la réponse acceptée ne faisait que les découper en espaces simples, comme: "Le ... ROUGE!", Ce qui n'est généralement pas ce dont vous aurez besoin.


3
J'ai utilisé ce modèle sur PHP et fonctionne. $ parts = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro

11

Plus robuste:

fonction trim (mot)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // change les caractères non imprimables en espaces
    return word.replace (/ ^ \ s + | \ s + $ / g, ''); // supprime les espaces de début / fin
}

8

je suggère

string = string.replace(/ +/g," ");

juste pour les espaces
OU

string = string.replace(/(\s)+/g,"$1");

pour transformer également plusieurs retours en un seul retour.


6

Je sais que je suis en retard à la fête, mais j'ai découvert une belle solution.

C'est ici:

var myStr = myStr.replace(/[ ][ ]*/g, ' ');

6

Voici une solution alternative si vous ne souhaitez pas utiliser replace (remplacez les espaces dans une chaîne sans utiliser replace javascript)

var str="The dog      has a long   tail, and it     is RED!";
var rule=/\s{1,}/g;
str = str.split(rule).join(" "); 
document.write(str);

5

Réponse complète non chiffrée pour les débutants et al.

C'est pour tous les mannequins comme moi qui testent les scripts écrits par certains d'entre vous qui ne fonctionnent pas.

Les 3 exemples suivants sont les étapes que j'ai suivies pour supprimer les caractères spéciaux ET les espaces supplémentaires sur les 3 sites Web suivants (qui fonctionnent tous parfaitement) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com} donc je sais que cela fonctionne parfaitement.

Nous les avons enchaînés avec plus de 50 à la fois et AUCUN problème.

// Cela a supprimé les caractères spéciaux + 0-9 et permet uniquement les lettres (majuscules et minuscules)

function NoDoublesPls1()
{
var str=document.getElementById("NoDoubles1");
var regex=/[^a-z]/gi;
str.value=str.value.replace(regex ,"");
}

// Cela a supprimé les caractères spéciaux et autorise uniquement les lettres (majuscules et minuscules) et 0-9 ET les espaces

function NoDoublesPls2()
{
var str=document.getElementById("NoDoubles2");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"");
}

// Cela a supprimé les caractères spéciaux et autorise uniquement les lettres (majuscules et minuscules) et les espaces 0-9 AND // Le .replace (/ \ s \ s + / g, "") à la fin supprime les espaces excessifs // lorsque je utilisé des guillemets simples, cela n'a pas fonctionné.

function NoDoublesPls3()
{    var str=document.getElementById("NoDoubles3");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"") .replace(/\s\s+/g, " ");
}

:: SUIVANT :: Enregistrer # 3 sous a .js// J'ai appelé le mien NoDoubles.js

:: SUIVANT :: Incluez votre JS dans votre page

 <script language="JavaScript" src="js/NoDoubles.js"></script>

Incluez ceci dans votre champ de formulaire :: tel que

<INPUT type="text" name="Name"
     onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Pour que ça ressemble à ça

<INPUT type="text" name="Name" onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Cela supprimera les caractères spéciaux, autorisera les espaces simples et supprimera les espaces supplémentaires.


Qu'est-ce qui se passe ici? Le formatage semble très, très cassé.
Nenotlep


1
var string = "The dog      has a long   tail, and it     is RED!";
var replaced = string.replace(/ +/g, " ");

Ou si vous souhaitez également remplacer les onglets:

var replaced = string.replace(/\s+/g, " ");

1
utiliser + semble plus propre mais il remplacera également les espaces simples par des espaces simples, un peu redondants et je ne suis pas sûr mais cela peut créer des problèmes de performances avec un texte beaucoup plus long.
ahmetunal

J'ai tendance à utiliser la solution la plus courte et la plus simple qui fonctionnera, et je ne m'inquiète de ce type d'optimisation que si je sais que je dois faire une correspondance avec une très grande chaîne, et à ce moment-là, je mesurerai différentes solutions pour voir laquelle Être plus rapide. Il peut être difficile de prévoir à l'avance ce qui sera le plus rapide sans test; par exemple, dans les interpréteurs JavaScript, certaines expressions régulières compliquées vous amèneront à passer d'une implémentation compilée JIT rapide à une implémentation lente interprétée.
Brian Campbell

1

Jquery a la fonction trim () qui transforme fondamentalement quelque chose comme ceci "FOo Bar" en "FOo Bar".

var string = "  My     String with  Multiple lines    ";
string.trim(); // output "My String with Multiple lines"

Il est beaucoup plus utile car il supprime automatiquement les espaces vides au début et à la fin de la chaîne. Aucune expression régulière nécessaire.


3
Comme vous l'avez dit, trim () supprime les espaces vides au début et à la fin de la chaîne, mais pas au milieu de la chaîne, donc, cela ne fonctionne pas dans ce cas, la sortie serait simplement "Ma chaîne avec plusieurs lignes". api.jquery.com/jQuery.trim
egvaldes

1

si remplacer n'est pas utilisé, string = string.split (/ \ W + /);


0
var myregexp = new RegExp(/ {2,}/g);

str = str.replace(myregexp,' ');

0

Nous pouvons utiliser l'expression rationnelle suivante expliquée à l'aide de la commande sed du système. Le regex similaire peut être utilisé dans d'autres langues et plates-formes.

Ajoutez le texte dans un fichier, dites test

manjeet-laptop:Desktop manjeet$ cat test
"The dog      has a long   tail, and it     is RED!"

Nous pouvons utiliser l'expression régulière suivante pour remplacer tous les espaces blancs par un seul espace

manjeet-laptop:Desktop manjeet$ sed 's/ \{1,\}/ /g' test
"The dog has a long tail, and it is RED!"

J'espère que cela sert le but


0

Essayez ceci pour remplacer plusieurs espaces par un seul espace.

<script type="text/javascript">
    var myStr = "The dog      has a long   tail, and it     is RED!";
    alert(myStr);  // Output 'The dog      has a long   tail, and it     is RED!'

    var newStr = myStr.replace(/  +/g, ' ');
    alert(newStr);  // Output 'The dog has a long tail, and it is RED!'
</script>

En savoir plus @ Remplacement de plusieurs espaces par un seul espace


0
var text = `xxx  df dfvdfv  df    
                     dfv`.split(/[\s,\t,\r,\n]+/).filter(x=>x).join(' ');

résultat:

"xxx df dfvdfv df dfv"

0

Pour plus de contrôle, vous pouvez utiliser le rappel de remplacement pour gérer la valeur.

value = "tags:HUNT  tags:HUNT         tags:HUNT  tags:HUNT"
value.replace(new RegExp(`(?:\\s+)(?:tags)`, 'g'), $1 => ` ${$1.trim()}`)
//"tags:HUNT tags:HUNT tags:HUNT tags:HUNT"

0

Ce script supprime tout espace blanc (plusieurs espaces, tabulations, retours, etc.) entre les mots et les coupes:

// Trims & replaces any wihtespacing to single space between words
String.prototype.clearExtraSpace = function(){
  var _trimLeft  = /^\s+/,
      _trimRight = /\s+$/,
      _multiple  = /\s+/g;

  return this.replace(_trimLeft, '').replace(_trimRight, '').replace(_multiple, ' ');
};

0

'mouse pointer touch' .replace (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") devrait faire l'affaire!


0

Je sais que nous devons utiliser l'expression régulière, mais lors d'une interview, on m'a demandé de le faire SANS UTILISER REGEX.

@slightlytyler m'a aidé à proposer l'approche ci-dessous.

const testStr = "I   LOVE    STACKOVERFLOW   LOL";

const removeSpaces = str  => {
  const chars = str.split('');
  const nextChars = chars.reduce(
    (acc, c) => {
      if (c === ' ') {
        const lastChar = acc[acc.length - 1];
        if (lastChar === ' ') {
          return acc;
        }
      }
      return [...acc, c];
    },
    [],
  );
  const nextStr = nextChars.join('');
  return nextStr
};

console.log(removeSpaces(testStr));


considérez: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.