Javascript ed espressioni regolari: divide la stringa e mantiene il separatore

Ho una stringa:

var string = "aaaaaa
† bbbb
‡ cccc"

E vorrei dividere questa stringa con il delimitatore
seguito da un carattere speciale.

Per farlo, sto usando questo:

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

Sto ottenendo ciò di cui ho bisogno, tranne che sto perdendo il delimitatore. Ecco l’esempio: http://jsfiddle.net/JwrZ6/1/

Come posso mantenere il delimitatore?

Usa lookahead positivo in modo che l’espressione regolare asserisca che il carattere speciale esiste, ma in realtà non corrisponde:

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

Guardalo in azione:

 var string = "aaaaaa
† bbbb
‡ cccc"; console.log(string.split(/
(?=&#?[a-zA-Z0-9]+;)/g));

Stavo avendo un problema simile ma leggermente diverso. Ad ogni modo, ecco alcuni esempi di tre diversi scenari per dove tenere il delinquente.

 "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"] 

Attenzione: il quarto funzionerà solo per dividere i singoli caratteri. ConnorsFan presenta un’alternativa :

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

Se si avvolge il delimitatore in paranthes, farà parte dell’array restituito.

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

A seconda della parte che si desidera mantenere cambia quale sottogruppo corrisponde

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

Potresti migliorare l’espressione ignorando il caso di lettere string.split (/ () & #? [A-z0-9] +; / gi);

E puoi abbinare gruppi predefiniti come questo: \d uguale a [0-9] e \w uguale a [a-zA-Z0-9_] . Ciò significa che la tua espressione potrebbe assomigliare a questo.

 string.split(/
(&#?[az\d]+;)/gi);

Esiste un buon riferimento alle espressioni regolari su JavaScriptKit .

ha risposto anche qui JavaScript Split Regular Expression mantiene il delimitatore

usa il modello di lookahead (? = pattern) nell’esempio regex

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

questo ti darà il seguente risultato.

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

Può anche essere diviso direttamente

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

dando lo stesso risultato

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

Una funzione di estensione divide la stringa con sottostringa o RegEx e il delimitatore viene inserito secondo il secondo parametro in anticipo o in retromarcia.

  String.prototype.splitKeep = function (splitter, ahead) { var self = this; var result = []; if (splitter != '') { var matches = []; // Getting mached value and its index var replaceName = splitter instanceof RegExp ? "replace" : "replaceAll"; var r = self[replaceName](splitter, function (m, i, e) { matches.push({ value: m, index: i }); return getSubst(m); }); // Finds split substrings var lastIndex = 0; for (var i = 0; i < matches.length; i++) { var m = matches[i]; var nextIndex = ahead == true ? m.index : m.index + m.value.length; if (nextIndex != lastIndex) { var part = self.substring(lastIndex, nextIndex); result.push(part); lastIndex = nextIndex; } }; if (lastIndex < self.length) { var part = self.substring(lastIndex, self.length); result.push(part); }; // Substitution of matched string function getSubst(value) { var substChar = value[0] == '0' ? '1' : '0'; var subst = ''; for (var i = 0; i < value.length; i++) { subst += substChar; } return subst; }; } else { result.add(self); }; return result; }; 

Il test:

  test('splitKeep', function () { // String deepEqual("1231451".splitKeep('1'), ["1", "231", "451"]); deepEqual("123145".splitKeep('1', true), ["123", "145"]); deepEqual("1231451".splitKeep('1', true), ["123", "145", "1"]); deepEqual("hello man how are you!".splitKeep(' '), ["hello ", "man ", "how ", "are ", "you!"]); deepEqual("hello man how are you!".splitKeep(' ', true), ["hello", " man", " how", " are", " you!"]); // Regex deepEqual("mhellommhellommmhello".splitKeep(/m+/g), ["m", "hellomm", "hellommm", "hello"]); deepEqual("mhellommhellommmhello".splitKeep(/m+/g, true), ["mhello", "mmhello", "mmmhello"]); }); 

Sto usando questo:

 String.prototype.splitBy = function (delimiter) { var delimiterPATTERN = '(' + delimiter + ')', delimiterRE = new RegExp(delimiterPATTERN, 'g'); return this.split(delimiterRE).reduce((chunks, item) => { if (item.match(delimiterRE)){ chunks.push(item) } else { chunks[chunks.length - 1] += item }; return chunks }, []) } 

Tranne che non dovresti String.prototype con String.prototype , quindi ecco una versione della funzione:

 var splitBy = function (text, delimiter) { var delimiterPATTERN = '(' + delimiter + ')', delimiterRE = new RegExp(delimiterPATTERN, 'g'); return text.split(delimiterRE).reduce(function(chunks, item){ if (item.match(delimiterRE)){ chunks.push(item) } else { chunks[chunks.length - 1] += item }; return chunks }, []) } 

Quindi potresti fare:

 var haystack = "aaaaaa
† bbbb
‡ cccc" var needle = '
&#?[a-zA-Z0-9]+;'; var result = splitBy(string, haystack) console.log( JSON.stringify( result, null, 2) )

E finirai con:

 [ "
† bbbb", "
‡ cccc" ]