Javascript和正则expression式:拆分string并保留分隔符

我有一个string:

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

我想分割这个string的分隔符<br />后面跟一个特殊的字符。

要做到这一点,我使用这个:

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

我得到了我所需要的,除了我正在失去分隔符。 这里是例子: http : //jsfiddle.net/JwrZ6/1/

我怎样才能保持分隔符?

使用正向预测,以便正则expression式声明特殊字符存在,但实际上并不匹配:

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

看到它的行动

更新:固定错字(移动文字;里面的超前包裹)

我有类似的,但稍有不同的问题。 无论如何,这里有三个不同场景的例子来说明在哪里保留删除者。

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

警告:第四个只会分割单个字符。 ConnorsFan提出了一个替代scheme :

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

如果将分隔符包装在parantheses中,它将成为返回数组的一部分。

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

取决于你想保持哪个部分的改变,你匹配哪个子组

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

你可以通过忽略字母string.split(/()&#?[a-z0-9] +; / gi)的情况来改善expression式。

您可以匹配预定义的组,例如: \d等于[0-9]\w等于[a-zA-Z0-9_] 。 这意味着你的表情可能看起来像这样。

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

JavaScriptKit有一个很好的正则expression式参考 。

在这里也回答了JavaScript Split Regular Expression保留了分隔符

在正则expression式示例中使用(?=模式)先行模式

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

这会给你以下结果。

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

也可以直接拆分

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

给出相同的结果

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

一个扩展函数将string与子string或RegEx分开,分隔符根据第二个参数提前或者后退。

  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; }; 

考试:

  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"]); }); 

我一直在使用这个:

 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 }, []) } 

除了你不应该搞乱String.prototype ,所以这是一个函数版本:

 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 }, []) } 

所以你可以这样做:

 var haystack = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc" var needle = '<br \/>&#?[a-zA-Z0-9]+;'; var result = splitBy(string, haystack) console.log( JSON.stringify( result, null, 2) ) 

最后你会得到:

 [ "<br />&dagger; bbbb", "<br />&Dagger; cccc" ] 
 function formatDate(dt, format) { var monthNames = [ "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Setiembre", "Octubre", "Noviembre", "Diciembre" ]; var Days = [ "Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado" ]; function pad(n, width, z) { z = z || '0'; n = n + ''; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; } function replace(val, date) { switch (val) { case 'yyyy': return date.getFullYear(); case 'YYYY': return date.getFullYear(); case 'yy': return (date.getFullYear() + "").substring(2); case 'YY': return (date.getFullYear() + "").substring(2); case 'MMMM': return monthNames[date.getMonth()]; case 'MMM': return monthNames[date.getMonth()].substring(0, 3); case 'MM': return pad(date.getMonth() + 1, 2); case 'M': return date.getMonth() + 1; case 'dd': return pad(date.getDate(), 2); case 'd': return date.getDate(); case 'DD': return Days[date.getDay()]; case 'D': return Days[date.getDay()].substring(0, 3); case 'HH': return pad(date.getHours(), 2); case 'H': return date.getHours(); case 'mm': return pad(date.getMinutes(), 2); case 'm': return date.getMinutes(); case 'ss': return pad(date.getSeconds(), 2); case 's': return date.getSeconds(); default: return val; } } var ds = format.split(/( |,|:)/g); var newFormat = ''; for (var i = 0; i < ds.length; i++) { newFormat += replace(ds[i], dt); } return newFormat; } var a = "2016-08-22T16:02:05.645Z"; var d = new Date(Date.parse(a)); // var d = new Date(); console.log(formatDate(d, 'd de MMMM, de YYYY H:mm'));