如何基于正则表达式拆分含Remix Icon的字符串并保留匹配的图标项在结果数组中?
解决包含Remix图标的字符串拆分问题
我懂你现在的痛点——之前用split拆分字符串时,总是会丢掉关键的图标标记,而且重复匹配的场景也处理不好。其实咱们换个思路,不用split,而是用正则匹配结合捕获组来同时保留普通文本和图标标记,就能完美解决这个需求。
核心思路
咱们需要一个能同时匹配两种内容的正则:
- 完整的Remix图标标记(格式
:ri-xxx:) - 图标标记之外的普通文本(包括空格、标点等,直到下一个图标或字符串结尾)
对应的正则表达式可以写成:
const iconRegex = /(:ri-[^:]*:)|([\s\S]+?(?=:ri-|$))/g;
正则拆解
(:ri-[^:]*:):捕获组1,精准匹配Remix图标标记——从:ri-开头,到下一个:结束,[^:]*确保不会跨冒号匹配无关内容|:逻辑“或”,匹配两个分支中的任意一种([\s\S]+?(?=:ri-|$)):捕获组2,匹配普通文本。[\s\S]覆盖所有字符(包括换行),+?是非贪婪匹配,(?=:ri-|$)是正向预查,确保匹配到下一个图标开头或者字符串结尾就停止,不会把后面的内容也吞掉
代码实现
咱们可以用matchAll或者循环exec来收集所有匹配的片段:
方法1:使用matchAll(ES6+)
const splitIconLabel = (label) => { const regex = /(:ri-[^:]*:)|([\s\S]+?(?=:ri-|$))/g; return Array.from(label.matchAll(regex), match => match[1] || match[2]); }; // 测试用例 console.log(splitIconLabel("Select an option:ri-arrow-down-s-line:")); // 输出: ["Select an option", ":ri-arrow-down-s-line:"] console.log(splitIconLabel("Download :ri-download-line: or upload :ri-upload-line:")); // 输出: ["Download ", ":ri-download-line:", " or upload ", ":ri-upload-line:"] console.log(splitIconLabel(":ri-download-line:")); // 输出: [":ri-download-line:"]
方法2:使用exec循环兼容旧环境
const splitIconLabel = (label) => { const regex = /(:ri-[^:]*:)|([\s\S]+?(?=:ri-|$))/g; const parts = []; let match; while ((match = regex.exec(label)) !== null) { // 取捕获组1(图标)或捕获组2(普通文本) parts.push(match[1] || match[2]); } return parts; };
为什么之前的split不好用?
split的本质是把字符串按分隔符切开,分隔符本身会被丢弃——这就是你之前拆分后看不到图标标记的原因。而咱们用match的方式,是主动去捕获所有需要保留的内容,不管是图标还是普通文本,都会被放进结果数组里,完美符合你的需求。
内容的提问来源于stack exchange,提问作者bacon-delight
相关产品推荐
相关产品推荐

