Javascript和正则expression式:拆分string并保留分隔符
我有一个string:
var string = "aaaaaa<br />† bbbb<br />‡ 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 />†", "bbbb", "<br />‡", "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 />† bbbb<br />‡ cccc" var needle = '<br \/>&#?[a-zA-Z0-9]+;'; var result = splitBy(string, haystack) console.log( JSON.stringify( result, null, 2) )
最后你会得到:
[ "<br />† bbbb", "<br />‡ 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'));