Comment diviser une chaîne avec plusieurs séparateurs en JavaScript? J'essaie de séparer les virgules et les espaces, mais, AFAIK, la fonction de fractionnement de JS ne prend en charge qu'un seul séparateur.
Comment diviser une chaîne avec plusieurs séparateurs en JavaScript? J'essaie de séparer les virgules et les espaces, mais, AFAIK, la fonction de fractionnement de JS ne prend en charge qu'un seul séparateur.
Réponses:
Passez une expression rationnelle comme paramètre:
js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!
Modifié 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!"
(hello world)|\|
qui ne fonctionnaient pas encore tout à fait. Des idées?
Vous pouvez passer une expression régulière 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 ensemble à agir comme un seul:
"1, 2, , 3".split(/(?:,| )+/)
["1", "2", "3"]
(Vous devez utiliser les parens non capturants (? :) car sinon, ils sont épissés dans le résultat. Ou vous pouvez être intelligent comme Aaron et utiliser une classe de caractères.)
(Exemples testés dans Safari + FF)
|
comme le montre Jesse.
Une autre méthode simple mais efficace consiste à utiliser split + join à plusieurs reprises.
"a=b,c:d".split('=').join(',').split(':').join(',').split(',')
Essentiellement, faire un fractionnement suivi d'une jointure est comme un remplacement global, ce qui remplace chaque séparateur par une virgule, puis une fois tous remplacés, il effectue un fractionnement final 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 un emballage String.prototype.split
pour plus de commodité (je pense que ma fonction est assez sûre - la seule considération est le surcoût supplémentaire des conditions (mineur) et le fait qu'il manque une implémentation de l'argument limit si un tableau est passé).
Assurez-vous d'inclure la splitMulti
fonction si vous utilisez cette approche ci-dessous pour l'enrouler simplement :). Il convient également de noter que certaines personnes désapprouvent l'extension des fonctionnalités intégrées (car de nombreuses personnes le font mal et des conflits peuvent survenir), donc en cas de doute, parlez à quelqu'un de plus âgé avant d'utiliser cela ou demandez SO 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!
for(var i = 0; i < tokens.length; i++)
et non for(var i = 1; i < tokens.length; i++)
?
tokens[1]
enregistrer une itération sous tokens[0] == tempchar
et nous nous tempchar
séparons après avoir répété tokens
pour terminer. Je mettrai à jour la réponse en conséquence merci @tic :).
Permet de rester simple: (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
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"]
'('
pour /(/g
remplacer tous les (
éléments - g
est le drapeau global pour RegExp - donc il recherche toutes les occurrences de (
pas le premier
Pour ceux d'entre vous qui souhaitent plus de personnalisation dans leur fonction de fractionnement, j'ai écrit un algorithme récursif qui fractionne une chaîne donnée avec une liste de caractères à fractionner. 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 flatten
fonction provient du code Rosetta
Vous pouvez simplement regrouper tous les caractères que vous souhaitez utiliser comme séparateurs soit individuellement soit collectivement dans une expression régulière et les transmettre à la fonction de fractionnement. Par exemple, vous pourriez écrire:
console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );
Et la sortie sera:
["dasdnk", "asd", "naks", ":d", "skldma"]
Salut par exemple si vous avez divisé et remplacé dans String 07:05:45 PM
var hour = time.replace("PM", "").split(":");
Résultat
[ '07', '05', '45' ]
Voici une nouvelle façon d'y parvenir 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:
source
Le résultat du code ci-dessus serait:
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.
Mon refactor de @Brian réponse
var string = 'and this is some kind of information and another text and simple and some egample or red or text';
var separators = ['and', 'or'];
function splitMulti(str, separators){
var tempChar = 't3mp'; //prevent short text separator in split down
//split by regex e.g. \b(or|and)\b
var re = new RegExp('\\b(' + separators.join('|') + ')\\b' , "g");
str = str.replace(re, tempChar).split(tempChar);
// trim & remove empty
return str.map(el => el.trim()).filter(el => el.length > 0);
}
console.log(splitMulti(string, separators))
Je trouve que l'une des principales raisons pour lesquelles j'ai besoin de cela est de diviser les chemins de fichiers sur /
et \
. C'est un peu une expression rationnelle difficile, donc je vais le poster ici pour référence:
var splitFilePath = filePath.split(/[\/\\]/);
Je pense que c'est plus facile si vous spécifiez ce que vous voulez laisser, au lieu de ce que vous voulez supprimer.
Comme si vous ne voulez avoir que des mots anglais, vous pouvez utiliser quelque chose comme ceci:
text.match(/[a-z'\-]+/gi);
Exemples (exécuter un extrait):
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>
À partir de la solution @ stephen-sweriduk (qui était 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);
qui redonne comme l'original:
[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]
Un moyen simple de le faire consiste à traiter chaque caractère de la chaîne avec chaque délimiteur 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;
};
Usage:
splix(string, delimiters...)
Exemple:
splix("1.23--4", ".", "--")
Retour:
["1", "23", "4"]
Je vais fournir une implémentation classique pour une telle fonction. Le code fonctionne dans presque toutes les versions de JavaScript et est en quelque sorte optimal.
Juste du code pur:
var text = "Create a function, that will return an array (of string), with the words inside the text";
println(getWords(text));
function getWords(text)
{
let startWord = -1;
let ar = [];
for(let i = 0; i <= text.length; i++)
{
let c = i < text.length ? text[i] : " ";
if (!isSeparator(c) && startWord < 0)
{
startWord = i;
}
if (isSeparator(c) && startWord >= 0)
{
let word = text.substring(startWord, i);
ar.push(word);
startWord = -1;
}
}
return ar;
}
function isSeparator(c)
{
var separators = [" ", "\t", "\n", "\r", ",", ";", ".", "!", "?", "(", ")"];
return separators.includes(c);
}
Vous pouvez voir le code s'exécuter dans la cour de récréation: https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf
Je ne connais pas les performances de RegEx, mais voici une autre alternative pour RegEx qui exploite HashSet natif et fonctionne à la place en complexité O (max (str.length, delimeter.length)):
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"]
Pas le meilleur moyen mais fonctionne pour diviser avec des séparateurs / délimiteurs 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>
J'utilise regexp:
str = 'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';
var strNew = str.match(/\w+/g);
// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]