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!"
Un apprenti
la source
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, ' ');
BalusC
la source
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.)

Edward Loper
la source
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,' ');
watain
la source
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+/, '') )
meder omuraliev
la source
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.

Nenotlep
la source
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.

Ethan
la source
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
}
Chris
la source
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.

Leonard Meagher
la source
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, ' ');
ToXic73
la source
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);
imos
la source
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.

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

Aussi une possibilité:

str.replace( /\s+/g, ' ' )
rfunduk
la source
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, " ");
Brian Campbell
la source
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.

Eryk Wróbel
la source
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 + /);

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

str = str.replace(myregexp,' ');
ahmetunal
la source
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

minhas23
la source
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

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

résultat:

"xxx df dfvdfv df dfv"
Boîte à outils
la source
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"
jackotonye
la source
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, ' ');
};
Oriol
la source
0

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

Ruwan Epage
la source
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));

xSachinx
la source
considérez: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes