Javascript and regex: split line and keep delimiter
I have a line:
var string = "aaaaaa<br />† bbbb<br />‡ cccc" And I would like to split this line with a separator <br /> followed by a special character.
For this, I use this:
string.split(/<br \/>&#?[a-zA-Z0-9]+;/g); I get what I need, except that I lose the delimiter. Here is an example: http://jsfiddle.net/JwrZ6/1/
How to save a separator?
Use a positive lookahead so that the regular expression claims that the special character exists, but does not actually match it:
string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g); Update: fixed typo (relocated literal ; inside lookahead parens)
I had a similar but small problem. Anyway, here are examples of three different scenarios where you can save the delimiter.
"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"] Warning: The fourth will only work for separating individual characters. ConnorsFan presents an alternative :
// Split a path, but keep the slashes that follow directories var str = 'Animation/rawr/javascript.js'; var tokens = str.match(/[^\/]+\/?|\//g); If you enclose the delimiter in parentheses, it will be part of the returned array.
string.split(/(<br \/>&#?[a-zA-Z0-9]+);/g); // returns ["aaaaaa", "<br />†", "bbbb", "<br />‡", "cccc"] Depending on which part you want to keep, which subgroup you match
string.split(/(<br \/>)&#?[a-zA-Z0-9]+;/g); // returns ["aaaaaa", "<br />", "bbbb", "<br />", "cccc"] You can improve the expression by ignoring the case of the letters String.split (/ () & # [-z0-9] +;? / );
And you can map such predefined groups as follows: \d equals [0-9] and \w equals [a-zA-Z0-9_] . This means that your expression may look like this.
string.split(/<br \/>(&#?[az\d]+;)/gi); There is a good regex link to JavaScriptKit .
answered also here Expand JavaScript Splititer regex
use a lookahead pattern (? = pattern) in a regular expression Example
var string = '500x500-11*90~1+1'; string = string.replace(/(?=[$-/:-?{-~!"^_`\[\]])/gi, ","); string = string.split(","); this will give you the following result.
[ '500x500', '-11', '*90', '~1', '+1' ] Can also be directly divided
string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi); gives the same result
[ '500x500', '-11', '*90', '~1', '+1' ] The extension function separates the string with a substring or RegEx, and the separator is placed forward or backward in the second parameter.
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:
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"]); }); I used this:
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 }, []) } Except that you should not be confused with String.prototype , so there is a version of the function here:
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 }, []) } So you can do:
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) ) And you will get:
[ "<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'));