I have a string 'w_600,h_600/c_overlay:{c_fit,w_570,h_256/c_crop,w_600,h_600/main_image},g_center,y_-157,x_0/c_overlay:{c_crop,w_300,h_300/main_image}/FFFFFF'
.
I want to split the string by /
, however, I want to use as a delimiter only /
that are not inside {...}
.
So the result after splitting the string would be:
['w_600,h_600', 'c_overlay{c_fit,w_570,h_256/c_crop,w_600,h_600/main_image},g_center,y_-157,x_0', 'c_overlay:{c_crop,w_300,h_300/main_image}', 'FFFFFF']
I tried to use .split(/(?<!{.*?)\/|(?<=}.*?)\//)
but it works incorrectly if there is more than one {...}
.
console.log('w_600,h_600/c_overlay:{c_fit,w_570,h_256/c_crop,w_600,h_600/main_image},g_center,y_-157,x_0/c_overlay:{c_crop,w_300,h_300/main_image}/FFFFFF'.split(/(?<!{.*?)\/|(?<=}.*?)\//))
CodePudding user response:
I'm not sure about a regex approach, but you could do it with a function like this:
function splitOnTokenOutsideOpenClose (input, splitToken, openToken, closeToken) {
let nestingCount = 0;
let current = '';
const result = [];
for (const unit of input) {
if (unit === openToken) nestingCount = 1;
else if (unit === closeToken) nestingCount -= 1;
if (unit !== splitToken || nestingCount > 0) {
current = unit;
continue;
}
result.push(current);
current = '';
}
if (current.length > 0) result.push(current);
return result;
}
const input = `w_600,h_600/c_overlay:{c_fit,w_570,h_256/c_crop,w_600,h_600/main_image},g_center,y_-157,x_0/c_overlay:{c_crop,w_300,h_300/main_image}/FFFFFF`;
const result = splitOnTokenOutsideOpenClose(input, '/', '{', '}');
console.log(result);
CodePudding user response:
From the above comment ...
... approach with a positive lookahead ...
/\/(?=(?:[^}] \{)|(?:[^}{] $)|$)/g
... which features three OR combined patterns in order to match/cover any possible delimiter occurrence.
// see ... [https://regex101.com/r/HYRvIM/1]
const regXSplit = /\/(?=(?:[^}] \{)|(?:[^}{] $)|$)/g;
console.log(
'w_600,h_600/c_overlay:{c_fit,w_570,h_256/c_crop,w_600,h_600/main_image},g_center,y_-157,x_0/c_overlay:{c_crop,w_300,h_300/main_image}/FFFFFF'
.split(regXSplit)
);
console.log(
'w_600,h_600/c_overlay:{c_fit,w_570,h_256/c_crop,w_600,h_600/main_image},g_center,y_-157,x_0/c_overlay:{c_crop,w_300,h_300/main_image}/FFFFFF/'
.split(regXSplit)
);
console.log(
'w_600,h_600/c_overlay:{c_fit,w_570,h_256/c_crop,w_600,h_600/main_im/age},g_center/,y_-157,x_0/c_overlay:{c_crop,w_/300,h_300/main_image}/FFF/FFF/'
.split(regXSplit)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }