如何改写正则表达式实现按多字符分隔符拆分目标字符串?
问题:含多字符分隔符的字符串拆分需求
原代码通过正则拆分空格和括号分隔的字符串:
let value = "(germany or croatia) and (denmark or hungary)" let tokens = value.split(/(?=[()\s])|(?<=[()\s])/g).filter(segment => segment.trim() != '');
生成结果数组:
['(', 'germany', 'or', 'croatia', ')', 'and', '(', 'denmark', 'or', 'hungary', ')']
现在需要拆分包含多字符分隔符的目标字符串:
(germany*or*croatia)*and*(denmark*or*hungary)
期望得到的拆分结果:
['(', 'germany', '*or*', 'croatia', ')', '*and*', '(', 'denmark', '*or*', 'hungary', ')']
由于*or*、*and*是多字符分隔符,直接修改原有split正则无法生效,该如何处理?
解决方案
推荐使用match方法替代split,直接匹配所有需要保留的片段,逻辑更直观高效:
let value = "(germany*or*croatia)*and*(denmark*or*hungary)"; let tokens = value.match(/\(|\)|(\*and\*|\*or\*)|[^\(\)*]+/g);
正则规则说明:
\(|\):匹配单个左括号(或右括号)(\*and\*|\*or\*):精确匹配多字符分隔符*and*或*or*(注意转义*,因为它是正则元字符,不转义会表示匹配前面内容0次或多次)[^\(\)*]+:匹配除括号()和*之外的连续字符,也就是germany、croatia这类目标内容
执行上述代码后,得到的结果正好是目标数组。
如果坚持要用split实现,可以结合正向/反向断言,但可读性和维护性较差:
let tokens = value.split(/(?<=[^\(\)*])(?=\*and\*|\*or\*)|(?<=\*and\*|\*or\*)(?=[^\(\)*])|(?=[()])|(?<=[()])/g).filter(seg => seg.trim() !== '');
该正则通过断言在多字符分隔符与普通内容之间、括号与其他内容之间添加拆分边界,再过滤空字符串得到结果。
内容的提问来源于stack exchange,提问作者sanjihan
相关产品推荐
相关产品推荐

