【问题标题】:How to specify string delimiter using regex?如何使用正则表达式指定字符串分隔符?
【发布时间】:2022-01-23 06:03:27
【问题描述】:

我有一个字符串'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'

我想用/ 分割字符串,但是,我只想将/ 用作不在{...} 内的分隔符。

所以拆分字符串后的结果是:

['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(/(?<!{.*?)\/|(?<=}.*?)\//),但如果有多个{...},它会无法正常工作。

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(/(?<!{.*?)\/|(?<=}.*?)\//))

【问题讨论】:

  • 最好的办法是不使用split。匹配喜欢
  • (?:[^/{}]+|(?:{.*?})|[{}])+(?=/)|(?<=/)(?:[^/{}]+|(?:{.*?})|[{}]) regex101.com/r/9OiL9y/1

标签: javascript regex string split


【解决方案1】:

我不确定正则表达式方法,但您可以使用如下函数:

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

【讨论】:

    【解决方案2】:

    从上面的评论...

    ... 具有积极前瞻的方法 .../\/(?=(?:[^}]+\{)|(?:[^}{]+$)|$)/g ... 具有三个 OR 组合模式,以匹配/覆盖任何可能出现的分隔符。

    编辑根据第四只鸟的建议

    上述模式可以简写为...\/(?=[^}]+{|[^}{]*$)

    // // see ... [https://regex101.com/r/HYRvIM/1]
    // const regXSplit = /\/(?=(?:[^}]+\{)|(?:[^}{]+$)|$)/g;
    
    // changed according to "The fourth bird"'s suggestion
    // 
    // see ... [https://regex101.com/r/HYRvIM/2]
    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; }

    【讨论】:

    • 您可以将模式缩短为\/(?=[^}]+{|[^}{]*$),因为非捕获组本身没有额外的目的,如果倒数第二个的量词是,则可以删除字符串末尾的最后一个交替可选的。见regex101.com/r/OGlyej/1
    • @Thefourthbird ...谢谢。根据您的建议编辑/改进。现在,看着它,很明显。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多