web-dev-qa-db-fra.com

Comment diviser une chaîne avec plusieurs séparateurs en javascript?

Comment diviser une chaîne avec plusieurs séparateurs en JavaScript? J'essaie de séparer les virgules et les espaces, mais, autant que je sache, la fonction de division de JS ne prend en charge qu'un seul séparateur.

397
sol

Transmettez une expression rationnelle en tant que paramètre:

js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!

Edité pour ajouter:

Vous pouvez obtenir le dernier élément en sélectionnant la longueur du tableau moins 1:

>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"

... et si le motif ne correspond pas:

>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"
577
Aaron Maenpaa

Vous pouvez passer une expression rationnelle dans L'opérateur de division de Javascript . Par exemple:

"1,2 3".split(/,| /) 
["1", "2", "3"]

Ou, si vous souhaitez autoriser plusieurs séparateurs à agir ensemble comme un seul:

"1, 2, , 3".split(/(?:,| )+/) 
["1", "2", "3"]

(Vous devez utiliser les parenthèses non-capturantes (? :) car sinon, le résultat sera fusionné. Vous pouvez aussi être intelligent comme Aaron et utiliser une classe de personnage.)

(Exemples testés dans Safari + FF)

154
Jesse Rusak

Une autre méthode simple mais efficace consiste à utiliser plusieurs fois split + join.

"a=b,c:d".split('=').join(',').split(':').join(',').split(',')

Effectuer une scission suivie d'une jointure s'apparente à un remplacement global. Il remplace donc chaque séparateur par une virgule. Une fois que tous les éléments ont été remplacés, il effectue une scission finale sur une virgule.

Le résultat de l'expression ci-dessus est:

['a', 'b', 'c', 'd']

En développant cela, vous pouvez également le placer dans une fonction:

function splitMulti(str, tokens){
        var tempChar = tokens[0]; // We can use the first token as a temporary join character
        for(var i = 1; i < tokens.length; i++){
            str = str.split(tokens[i]).join(tempChar);
        }
        str = str.split(tempChar);
        return str;
}

Usage: 

splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]

Si vous utilisez beaucoup cette fonctionnalité, il pourrait même être utile d’envisager l’emballage de String.prototype.split pour plus de commodité (je pense que ma fonction est relativement sûre: la seule considération à prendre en compte est la surcharge supplémentaire des conditionals (mineur) et le fait argument si un tableau est passé).

Assurez-vous d’inclure la fonction splitMulti si vous utilisez cette approche pour l’envoyer ci-dessous: Il convient également de noter que certaines personnes désapprouvent les extensions prédéfinies (comme beaucoup le font mal et que des conflits peuvent survenir). En cas de doute, parlez-en à quelqu'un de plus haut placé avant de l'utiliser ou demandez à SO :) 

    var splitOrig = String.prototype.split; // Maintain a reference to inbuilt fn
    String.prototype.split = function (){
        if(arguments[0].length > 0){
            if(Object.prototype.toString.call(arguments[0]) == "[object Array]" ) { // Check if our separator is an array
                return splitMulti(this, arguments[0]);  // Call splitMulti
            }
        }
        return splitOrig.apply(this, arguments); // Call original split maintaining context
    };

Usage:

var a = "a=b,c:d";
    a.split(['=', ',', ':']); // ["a", "b", "c", "d"]

// Test to check that the built-in split still works (although our wrapper wouldn't work if it didn't as it depends on it :P)
        a.split('='); // ["a", "b,c:d"] 

Prendre plaisir!

33
Brian

Restons simples: (ajouter un "[] ​​+" à votre RegEx signifie "1 ou plus")

Cela signifie que "+" et "{1,}" sont identiques.

var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept
12
htmlfarmer

Méthode délicate:

var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]
11
user669677

Pour ceux d'entre vous qui veulent plus de personnalisation dans leur fonction de division, j'ai écrit un algorithme récursif qui divise une chaîne donnée avec une liste de caractères à scinder. J'ai écrit ceci avant de voir le post ci-dessus. J'espère que cela aide certains programmeurs frustrés.

splitString = function(string, splitters) {
    var list = [string];
    for(var i=0, len=splitters.length; i<len; i++) {
        traverseList(list, splitters[i], 0);
    }
    return flatten(list);
}

traverseList = function(list, splitter, index) {
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != list[index].split(splitter)) ? list[index] = list[index].split(splitter) : null;
        (list[index].constructor === Array) ? traverseList(list[index], splitter, 0) : null;
        (list.constructor === Array) ? traverseList(list, splitter, index+1) : null;    
    }
}

flatten = function(arr) {
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? flatten(val) : val);
    },[]);
}

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
splitString(stringToSplit, splitList);

L'exemple ci-dessus renvoie: ["people", "and", "other", "things"]

Remarque: La fonction flatten a été prise à partir de Code Rosetta

7
Stephen Sweriduk

Vous pouvez simplement regrouper tous les caractères que vous souhaitez utiliser en tant que séparateurs, soit séparément, soit collectivement, dans une expression régulière et les transmettre à la fonction de division. Par exemple, vous pouvez écrire:

console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );

Et le résultat sera:

["dasdnk", "asd", "naks", ":d", "skldma"]
6
PeterKA

Peut-être devriez-vous remplacer par une chaîne de caractères pour transformer un séparateur en un autre séparateur de manière à ne disposer que d'un séparateur dans votre division.

3
TheTXI

Bonjour par exemple si vous avez scindé et remplacé dans String 07:05:45 PM 

var hour = time.replace("PM", "").split(":");

Résultat

[ '07', '05', '45' ]
2
Ezequiel García
a = "a=b,c:d"

array = ['=',',',':'];

for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }

cela retournera la chaîne sans caractère spécial.

1
gaurav krishna

À partir de la solution @ stephen-sweriduk (la plus intéressante pour moi!), Je l’ai légèrement modifiée pour la rendre plus générique et réutilisable:

/**
 * Adapted from: http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript
*/
var StringUtils = {

  /**
   * Flatten a list of strings
   * http://rosettacode.org/wiki/Flatten_a_list
   */
  flatten : function(arr) {
    var self=this;
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? self.flatten(val) : val);
    },[]);
  },

  /**
   * Recursively Traverse a list and apply a function to each item
   * @param list array
   * @param expression Expression to use in func
   * @param func function of (item,expression) to apply expression to item
   *
   */
  traverseListFunc : function(list, expression, index, func) {
    var self=this;
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != func(list[index], expression)) ? list[index] = func(list[index], expression) : null;
        (list[index].constructor === Array) ? self.traverseListFunc(list[index], expression, 0, func) : null;
        (list.constructor === Array) ? self.traverseListFunc(list, expression, index+1, func) : null;
    }
  },

  /**
   * Recursively map function to string
   * @param string
   * @param expression Expression to apply to func
   * @param function of (item, expressions[i])
   */
  mapFuncToString : function(string, expressions, func) {
    var self=this;
    var list = [string];
    for(var i=0, len=expressions.length; i<len; i++) {
        self.traverseListFunc(list, expressions[i], 0, func);
    }
    return self.flatten(list);
  },

  /**
   * Split a string
   * @param splitters Array of characters to apply the split
   */
  splitString : function(string, splitters) {
    return this.mapFuncToString(string, splitters, function(item, expression) {
      return item.split(expression);
    })
  },

}

et alors

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);

cela donne comme l'original:

[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]
1
loretoparisi

Une méthode simple consiste à traiter chaque caractère de la chaîne avec chaque séparateur et à créer un tableau des divisions

splix = function ()
{
  u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0;

  for (i = 0; i < u.length; ++i)
  {
    for (j = 0; j < v.length; ++j)
    {
      if (u.slice(i, i + v[j].length) == v[j])
      {
        y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1];
      };
    };
  };

  return w;
};

console.logg = function ()
{
  document.body.innerHTML += "<br>" + [].slice.call(arguments).join();
}

splix = function() {
  u = [].slice.call(arguments);
  v = u.slice(1);
  u = u[0];
  w = [u];
  x = 0;
  console.logg("Processing: <code>" + JSON.stringify(w) + "</code>");

  for (i = 0; i < u.length; ++i) {
    for (j = 0; j < v.length; ++j) {
      console.logg("Processing: <code>[\x22" + u.slice(i, i + v[j].length) + "\x22, \x22" + v[j] + "\x22]</code>");
      if (u.slice(i, i + v[j].length) == v[j]) {
        y = w[x].split(v[j]);
        w[x] = y[0];
        w[++x] = y[1];
        console.logg("Currently processed: " + JSON.stringify(w) + "\n");
      };
    };
  };

  console.logg("Return: <code>" + JSON.stringify(w) + "</code>");
};

setTimeout(function() {
  console.clear();
  splix("1.23--4", ".", "--");
}, 250);
@import url("http://fonts.googleapis.com/css?family=Roboto");

body {font: 20px Roboto;}

Usage: splix(string, delimiters...)

Exemple: splix("1.23--4", ".", "--")

Retours: ["1", "23", "4"]

1
harr-will

Je trouve que l'une des principales raisons pour lesquelles j'ai besoin de cela est de fractionner les chemins de fichiers à la fois sur / et \ C'est un peu une regex délicate donc je vais le poster ici pour référence:

var splitFilePath = filePath.split(/[\/\\]/);
0
AlliterativeAlice

Voici un nouveau moyen d'atteindre le même résultat dans ES6 :

function SplitByString(source, splitBy) {
  var splitter = splitBy.split('');
  splitter.Push([source]); //Push initial value

  return splitter.reduceRight(function(accumulator, curValue) {
    var k = [];
    accumulator.forEach(v => k = [...k, ...v.split(curValue)]);
    return k;
  });
}

var source = "abc,def#hijk*lmn,opq#rst*uvw,xyz";
var splitBy = ",*#";
console.log(SplitByString(source, splitBy));

Veuillez noter dans cette fonction:

  • Pas de regex impliqué
  • Retourne la valeur fractionnée dans le même ordre que dans source

Le résultat du code ci-dessus serait:

enter image description here

0
Vishnu

Je ne connais pas les performances de RegEx, mais voici une autre alternative. RegEx exploite HashSet en natif et fonctionne en complexité O (max (str.length, delimeter.length)) à la place:

var multiSplit = function(str,delimiter){
    if (!(delimiter instanceof Array))
        return str.split(delimiter);
    if (!delimiter || delimiter.length == 0)
        return [str];
    var hashSet = new Set(delimiter);
    if (hashSet.has(""))
        return str.split("");
    var lastIndex = 0;
    var result = [];
    for(var i = 0;i<str.length;i++){
        if (hashSet.has(str[i])){
            result.Push(str.substring(lastIndex,i));
            lastIndex = i+1;
        }
    }
    result.Push(str.substring(lastIndex));
    return result;
}

multiSplit('1,2,3.4.5.6 7 8 9',[',','.',' ']);
// Output: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

multiSplit('1,2,3.4.5.6 7 8 9',' ');
// Output: ["1,2,3.4.5.6", "7", "8", "9"]
0
Orhun Alp Oral

Pas le meilleur moyen mais fonctionne pour diviser en séparateurs/séparateurs multiples et différents

html

<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>

javascript

<script>
function myFunction() {

var str = "How : are | you doing : today?";
var res = str.split(' | ');

var str2 = '';
var i;
for (i = 0; i < res.length; i++) { 
    str2 += res[i];

    if (i != res.length-1) {
      str2 += ",";
    }
}
var res2 = str2.split(' : ');

//you can add countless options (with or without space)

document.getElementById("demo").innerHTML = res2;
</script>
0
Stavros

Je pense que c'est plus facile si vous spécifiez ce que vous voulez laisser plutôt que ce que vous voulez supprimer.

Comme si vous ne voulez que des mots anglais, vous pouvez utiliser quelque chose comme ceci:

text.match(/[a-z'\-]+/gi);

Exemples (extrait de code):

var R=[/[a-z'\-]+/gi,/[a-z'\-\s]+/gi];
var s=document.getElementById('s');
for(var i=0;i<R.length;i++)
 {
  var o=document.createElement('option');
  o.innerText=R[i]+'';
  o.value=i;
  s.appendChild(o);
 }
var t=document.getElementById('t');
var r=document.getElementById('r');

s.onchange=function()
 {
  r.innerHTML='';
  var x=s.value;
  if((x>=0)&&(x<R.length))
   x=t.value.match(R[x]);
  for(i=0;i<x.length;i++)
   {
    var li=document.createElement('li');
    li.innerText=x[i];
    r.appendChild(li);
   }
 }
<textarea id="t" style="width:70%;height:12em">even, test; spider-man

But saying o'er what I have said before:
My child is yet a stranger in the world;
She hath not seen the change of fourteen years,
Let two more summers wither in their pride,
Ere we may think her ripe to be a bride.

—Shakespeare, William. The Tragedy of Romeo and Juliet</textarea>

<p><select id="s">
 <option selected>Select a regular expression</option>
 <!-- option value="1">/[a-z'\-]+/gi</option>
 <option value="2">/[a-z'\-\s]+/gi</option -->
</select></p>
 <ol id="r" style="display:block;width:auto;border:1px inner;overflow:scroll;height:8em;max-height:10em;"></ol>
</div>

0
ESL