How to split string('a|b\\|c') to array('a', 'b|c'') in js?

Viewed 119

I want to split a string in 2 parts separated by '|', but not separated if '|' before is '\'.

Input

example_str = 'a|b\\|c'

Output

st1 ='a'
st2 ='b|c'
5 Answers

These kinds of task can be solved by state machine approach. Simply saying, in your case: you need to build cycle for each character. When we see \ we move current state to ESCAPE and on next interaction when we are in ESCAPE state we need to reset state to normal state. If we see | and we are not in ESCAPE state we need to copy this part of text and push it to array.

You should also decide, what should be the result for a|b\\|c.

You can replace the \| with a unique string, then split on the pipe, then replace the unique string back to \|

Like this, https://jsfiddle.net/gb3Ljugc/

const aUniqueStringNotFoundInData = '___UNIQUE_____';
let x = 'a|b\\|c'.replace('\\\|', aUniqueStringNotFoundInData).split('\|');
x = x.reduce((acc, val) => {
    val = val.replace(aUniqueStringNotFoundInData, '\\\|');
  return acc.concat(val);
},[])
console.log(x);
var test = "a|b\\|c";
test = test.replace('\\|','%%');
var testArray = test.split('|')


for(x = 0; x < testArray.length; x++)
{
    testArray[x] = testArray[x].replace('%%', '\\|');
}

var st1 = testArray[0];
var st2 = testArray[1];

I believe that there is no way to achieve what you're asking about because in JS string literals 'a|b\|c' and 'a|b|c' are equivalent. Check this please:

var s1 = 'a|b\|c';
var s2 = 'a|b|c';
console.log(s1 === s2);

Still if input string is correctly escaped you may try combine split with reduce. Sorry for ES6 spread operator

var s = 'a|b\\|c';
var arr =  s.split('|')
var result = arr.reduce((acc, item) => {
    if (acc.length && acc[acc.length - 1] && acc[acc.length - 1].endsWith('\\')) {
        acc[acc.length - 1] = acc[acc.length - 1].substring(0, acc.length - 1) + '|' + item;
        return acc;
    }
    return [...acc, item];
}
, []);

You lose the first pipe anyhow, so replace it with something else and then split by that:

const [str1, str2] = 'a|b\|c'.replace('|', ' ').split(' ');
Related