Home > Back-end >  How to specify string delimiter using regex?
How to specify string delimiter using regex?

Time:12-22

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:

TS Playground

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; }

  • Related