I could come up with two solutions. One that is based on adjusting array contents and one that uses a regex.
Solution 1:
Approach: Split on :
, then shovel elements into new array and glue those back together that should not have been split.
function splitcolon(input) {
var inparts = input.split(":");
var outparts = [];
var splitwaslegit = true;
inparts.forEach(function(part) {
if (splitwaslegit) {
outparts.push(part);
} else { // the split was not justified, so reverse it by gluing this part to the previous one
outparts[outparts.length-1] += ":" + part;
}
// the next split was legit if this part doesn't end on \\
splitwaslegit = (part.substring(part.length-2) !== "\\\\");
});
return outparts;
}
Tested in chrome:
splitcolon("dtet:du\\\\,eduh ei\\\\:di:e,j")
(3) ["dtet", "du\\,eduh ei\\:di", "e,j"]
Note:
Could of course also use a for
loop or underscore's each
instead of forEach
Solution 2:
Approach: If there is any char or string of which you can be 100% sure that it won't be in the input, then you can use that char/string as a temporary delimiter inserted by a regex like this:
var tmpdelim = "\x00"; // must *never* ever occur in input string
var input = "dtet:du\\\\,eduh ei\\\\:di:e,j";
input.replace(/(^.?|[^\\].|.[^\\]):/g, "$1" + tmpdelim).split(tmpdelim);
Result:
(3) ["dtet", "du\\,eduh ei\\:di", "e,j"]
Explanation of regular expression /(^.?|[^\\].|.[^\\]):/g
:
/
- start of regex
(
- matching group 1 start
^.?
- we're at input start or any single char away from it (the escape requires 2)
|
- or
[^\\].
- any char that is not a \
followed by any other char
|
- or
.[^\\]
- any char followed by anything other than a \
)
- matching group 1 stop
:
- the matching group (which can't be \\
) must be followed by a :
/
- end of regex
g
- regex modifier global (match all occurances, not just the first)
which we replace with $1 + tmpdelim
, so with whatever was in matching group 1, followed by our special delimiter (instead of :
) which we can then use for splitting.
Bonus solution
Manjo Verma's answer as one-liner:
input.split("").reverse().join("").split(/:(?!\\\\)/).reverse().map(x => x.split("").reverse().join(""));
Result:
(3) ["dtet", "du\\,eduh ei\\:di", "e,j"]