我在Javascript中寻找一种方法,将字符串拆分为基于"starting"one_answers";ending"分隔符,而不是一个分隔符,如str.split目前所做的。
例如,如果我有这个字符串:
const str = '{lang}_{cmp_abbrev}_{cmp_type}_{pl_abbrev}_{w}x{h}_d{dv}c{cv}'
结果:
str.mySplit('{', '}');
将是这样的:
[
'{lang}',
'_',
'{cmp_abbrev}',
'_',
'{cmp_type}',
'_',
'{pl_abbrev}',
'_',
'{w}',
'x',
'{h}',
'_d',
'{dv}',
'c',
'{cv}'
]
因此,在决定如何分割字符串时,它将考虑2个字符而不是一个字符。
Regex救援!
const str = '{lang}_{cmp_abbrev}_{cmp_type}_{pl_abbrev}_{w}x{h}_d{dv}c{cv}'
const values = [...str.matchAll(/w+|{w+}/g)].flat()
console.log(values)
Array#split
可以接受带有捕获组的正则表达式:
'foo{bar}baz{}!'.split(/({.*?})/g)
//=> ['foo', '{bar}', 'baz', '{}', '!']
请注意可以生成空字符串,例如
'{foo}bar{baz}'.split(/({.*?})/g)
//=> ['', '{foo}', 'bar', '{baz}', '']
'{foo}{bar}{baz}'.split(/({.*?})/g)
//=> ['', '{foo}', '', '{bar}', '', '{baz}', '']
但这既正常又在意料之中。如果不需要,可以将它们过滤掉:
'{foo}{bar}{baz}'.split(/({.*?})/g).filter(Boolean)
//=> ['{foo}', '{bar}', '{baz}']
对于初始字符串,我们有:
'{lang}_{cmp_abbrev}_{cmp_type}_{pl_abbrev}_{w}x{h}_d{dv}c{cv}'.split(/({.*?})/g).filter(Boolean)
//=> ['{lang}', '_', '{cmp_abbrev}', '_', '{cmp_type}', '_', '{pl_abbrev}', '_', '{w}', 'x', '{h}', '_d', '{dv}', 'c', '{cv}']
如果您的示例字符串始终具有该格式,则可以使用分割并捕获组中的1个或多个单词字符,以保留在分割后的结果中。
然后在左边断言一个结束花括号,在右边断言一个开始花括号:
(?<=})(w+)(?={)
查看regex演示。
const str = '{lang}_{cmp_abbrev}_{cmp_type}_{pl_abbrev}_{w}x{h}_d{dv}c{cv}'
const values = str.match(/{[^{}]*}|[^s{}]+/g)
console.log(values)
另一种选择是从{...}
匹配或匹配除{
和}
以外的1+非空白字符使用一个否定的字符类:
{[^{}]*}|[^s{}]+
查看另一个正则表达式演示。
const str = '{lang}_{cmp_abbrev}_{cmp_type}_{pl_abbrev}_{w}x{h}_d{dv}c{cv}'
const values = str.match(/{[^{}]*}|[^s{}]+/g)
console.log(values)