JavaScript正则表达式:按指定单词外内容分割字符串
问题:用正则分割字符串,保留特定单词组成的连续片段
需求说明
需要将字符串按所有非ping/pong的单词分割,最终得到由ping和pong通过-连接的连续片段数组:
示例1
输入字符串:
const s = 'pong-ping-bink-ping-pong-ping-donk';
期望输出:
"pong-ping", "ping-pong-ping"
示例2
输入字符串:
const s = 'ping-pong-ping-pong-fong-song-pong-bing';
期望输出:
"ping-pong-ping-pong", "pong"
现有代码问题
你当前的代码报错Uncaught SyntaxError: Invalid regular expression: Nothing to repeat,问题出在正则/-(?!ping|?!pong)-/g:
- 逻辑错误:
(?!ping|?!pong)的逻辑是“不是ping,或者不是pong”,这等于永远为真,完全不符合需求; - 语法错误:错误的预查嵌套结构让正则引擎无法识别有效模式,导致报错。
解决方法
方法一:直接匹配目标片段(推荐)
不需要分割,直接匹配所有由ping/pong组成的连续片段,逻辑更直观:
// 匹配连续的ping/pong组合 const regex = /(?:ping|pong)(?:-(?:ping|pong))*/g; // 测试示例1 const s1 = 'pong-ping-bink-ping-pong-ping-donk'; console.log(s1.match(regex)); // ["pong-ping", "ping-pong-ping"] // 测试示例2 const s2 = 'ping-pong-ping-pong-fong-song-pong-bing'; console.log(s2.match(regex)); // ["ping-pong-ping-pong", "pong"]
正则解释:
(?:ping|pong):匹配开头的ping或pong(非捕获组,避免冗余分组);(?:-(?:ping|pong))*:匹配0次或多次“-+ping/pong”的结构,确保片段是连续的目标单词组合。
方法二:修正split的正则
如果一定要用split,需要匹配包含至少一个非ping/pong单词的分隔块:
// 匹配包含非ping/pong单词的分隔块 const regex = /-?(?:(?!ping|pong)[^-]+)(?:-(?!ping|pong)[^-]+)*-?/g; // 测试示例1 const s1 = 'pong-ping-bink-ping-pong-ping-donk'; const result1 = s1.split(regex).filter(Boolean); // 过滤空字符串 console.log(result1); // ["pong-ping", "ping-pong-ping"] // 测试示例2 const s2 = 'ping-pong-ping-pong-fong-song-pong-bing'; const result2 = s2.split(regex).filter(Boolean); console.log(result2); // ["ping-pong-ping-pong", "pong"]
正则解释:
-?:匹配可选的开头/结尾-;(?:(?!ping|pong)[^-]+):匹配一个非ping/pong的单词;(?:-(?!ping|pong)[^-]+)*:匹配连续的“-+ 非目标单词”结构;filter(Boolean):移除分割后可能出现的空字符串。
内容的提问来源于stack exchange,提问作者upcast
相关产品推荐
相关产品推荐

