187 votes

Javascript et regex : diviser une chaîne et garder le séparateur

J'ai une corde :

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc"

Et je voudrais diviser cette chaîne avec le délimiteur <br /> suivi d'un caractère spécial.

Pour ce faire, j'utilise ceci :

string.split(/<br \/>&#?[a-zA-Z0-9]+;/g);

J'obtiens ce dont j'ai besoin, sauf que je perds le délimiteur. Voici l'exemple : http://jsfiddle.net/JwrZ6/1/

Comment puis-je conserver le délimiteur ?

240voto

jichi Points 561

J'avais un problème similaire mais légèrement différent. Quoi qu'il en soit, voici des exemples de trois scénarios différents concernant l'emplacement du délimiteur.

"1、2、3".split("、") == ["1", "2", "3"]
"1、2、3".split(/(、)/g) == ["1", "、", "2", "、", "3"]
"1、2、3".split(/(?=、)/g) == ["1", "、2", "、3"]
"1、2、3".split(/(?!、)/g) == ["1、", "2、", "3"]
"1、2、3".split(/(.*?、)/g) == ["", "1、", "", "2、", "3"]

Attention : La quatrième ne fonctionne que pour diviser des caractères uniques. ConnorsFan présente une alternative :

// Split a path, but keep the slashes that follow directories
var str = 'Animation/rawr/javascript.js';
var tokens = str.match(/[^\/]+\/?|\//g);

124voto

Jon Points 194296

Utilice (positive) lookahead de sorte que l'expression régulière affirme que le caractère spécial existe, mais ne le fait pas correspondre :

string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g);

Voyez-le en action :

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc";
console.log(string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g));

75voto

Torsten Walter Points 3213

Si vous mettez le délimiteur entre parenthèses, il fera partie du tableau retourné.

string.split(/(<br \/>&#?[a-zA-Z0-9]+);/g);
// returns ["aaaaaa", "<br />&dagger;", "bbbb", "<br />&Dagger;", "cccc"]

En fonction de la partie que vous voulez conserver, changez le sous-groupe que vous faites correspondre.

string.split(/(<br \/>)&#?[a-zA-Z0-9]+;/g);
// returns ["aaaaaa", "<br />", "bbbb", "<br />", "cccc"]

Vous pourriez améliorer l'expression en ignorant la casse des lettres string.split(/()&# ?[a-z0-9]+;/gi) ;

Et vous pouvez correspondre à des groupes prédéfinis comme celui-ci : \d est égal à [0-9] y \w est égal à [a-zA-Z0-9_] . Cela signifie que votre expression pourrait ressembler à ceci.

string.split(/<br \/>(&#?[a-z\d]+;)/gi);

Il y a une bonne Référence pour les expressions régulières sur JavaScriptKit .

5voto

Fry Points 39

Répondu ici aussi JavaScript Split Expression régulière garder le délimiteur

utiliser le motif (?=modèle) lookahead dans la regex exemple

var string = '500x500-11*90~1+1';
string = string.replace(/(?=[$-/:-?{-~!"^_`\[\]])/gi, ",");
string = string.split(",");

cela vous donnera le résultat suivant.

[ '500x500', '-11', '*90', '~1', '+1' ]

Peut également être divisé directement

string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi);

donnant le même résultat

[ '500x500', '-11', '*90', '~1', '+1' ]

4voto

SwiftNinjaPro Points 60

J'ai fait une modification à la réponse de jichi, et je l'ai mise dans une fonction qui supporte aussi les lettres multiples.

String.prototype.splitAndKeep = function(separator, method='seperate'){
    var str = this;
    if(method == 'seperate'){
        str = str.split(new RegExp(`(${separator})`, 'g'));
    }else if(method == 'infront'){
        str = str.split(new RegExp(`(?=${separator})`, 'g'));
    }else if(method == 'behind'){
        str = str.split(new RegExp(`(.*?${separator})`, 'g'));
        str = str.filter(function(el){return el !== "";});
    }
    return str;
};

La 3ème méthode de réponse de jichi ne fonctionnait pas dans cette fonction, j'ai donc pris la 4ème méthode, et supprimé les espaces vides pour obtenir le même résultat.

éditer : deuxième méthode qui excepte un tableau pour diviser char1 ou char2

String.prototype.splitAndKeep = function(separator, method='seperate'){
    var str = this;
    function splitAndKeep(str, separator, method='seperate'){
        if(method == 'seperate'){
            str = str.split(new RegExp(`(${separator})`, 'g'));
        }else if(method == 'infront'){
            str = str.split(new RegExp(`(?=${separator})`, 'g'));
        }else if(method == 'behind'){
            str = str.split(new RegExp(`(.*?${separator})`, 'g'));
            str = str.filter(function(el){return el !== "";});
        }
        return str;
    }
    if(Array.isArray(separator)){
        var parts = splitAndKeep(str, separator[0], method);
        for(var i = 1; i < separator.length; i++){
            var partsTemp = parts;
            parts = [];
            for(var p = 0; p < partsTemp.length; p++){
                parts = parts.concat(splitAndKeep(partsTemp[p], separator[i], method));
            }
        }
        return parts;
    }else{
        return splitAndKeep(str, separator, method);
    }
};

l'usage :

str = "first1-second2-third3-last";

str.splitAndKeep(["1", "2", "3"]) == ["first", "1", "-second", "2", "-third", "3", "-last"];

str.splitAndKeep("-") == ["first1", "-", "second2", "-", "third3", "-", "last"];

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X