如何使用正则表达式指定字符串分隔符?

Posted

技术标签:

【中文标题】如何使用正则表达式指定字符串分隔符?【英文标题】: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_overlayc_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 【参考方案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 ...谢谢。根据您的建议编辑/改进。现在,看着它,很明显。

以上是关于如何使用正则表达式指定字符串分隔符?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 正则表达式

正则表达式怎么匹配前面紧跟某个字符串的字符

如何使用正则表达式分隔字符串

如何使用正则表达式验证逗号分隔的字符串 [重复]

正则表达式

Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置expand参数将拆分结果列表内容转化为多列数据并添加到原数据中replace函数基于正则表达式替换字符串数据列中的匹配内容