如何用正则表达式为指定数组符号添加^包裹并补空格?
问题描述
需要将指定数组中的每个符号用^包裹,示例如下:
const signs = [',', '!!', '?!', '!?', '...', '..', '.', '?', '؟!', '!؟', '!', '؟', ':']; const input = 'this is, a text?' // 期望结果 : 'this is ^,^ a text ^?^'
注意:若符号与相邻单词之间无空格,需自动添加空格。
目前我用了一个仍在开发中的复杂函数实现该功能,但觉得可以用正则表达式更简便完成,请问如何用正则实现?
附当前开发中的函数:
function modifySelectedPortion(e) { const translateSigns = translationInput.value.split(' ').filter(s => acceptedSigns.includes(s)); if(translateSigns.length) { console.log(translateSigns); } const selectionEnd = translationInput.selectionEnd; const selectionStart = translationInput.selectionStart; const color = e.target.dataset.color; if(!color) return; const signs = { blue: '|', red: '$', orange: '^', purple: '#', green: '~', quote: '@', braket: 'braket', pranthesis: 'pranthesis' }; if(color == 'none') return reset(); if(color == 'copy') return copy(); const signA = color == 'bracket' ? '[ ' : color == 'pranthesis' ? '( ' : signs[color]; const signB = color == 'bracket' ? ' ]' : color == 'pranthesis' ? ' )' : signs[color]; const point = translationInput.value[selectionEnd - 1]; const increase = ['bracket', 'pranthesis'].includes(color) ? 2 : 1; // const start = translationInput.selectionStart; const finish = point == ' ' ? selectionEnd + increase - 1: selectionEnd + increase; const textStart = translationInput.value; translationInput.value = textStart.substring(0, selectionStart) + signA + textStart.substring(selectionStart); const textFinish = translationInput.value; translationInput.value = textFinish.substring(0, finish) + signB + textFinish.substring(finish); translationInputPreview(); function reset() { for(let key of Object.keys(signs)) { translationInput.value = translationInput.value.replaceAll(signs[key], ''); } translationInputPreview(); } function copy() { translationInput.value = getCookie('translate-input') || ''; translationInputPreview(); } }
正则表达式实现方案
核心思路
- 优先匹配长符号:避免短符号拆分长符号(比如先匹配
!会把!!拆成两个单独的!),所以先对符号数组按长度从长到短排序。 - 转义正则特殊字符:
.、?等符号是正则保留字符,必须转义后才能准确匹配。 - 处理空格:捕获符号前后的空格,自动补充缺失的空格,保证符号与单词间有分隔。
完整代码实现
const signs = [',', '!!', '?!', '!?', '...', '..', '.', '?', '؟!', '!؟', '!', '؟', ':']; // 按符号长度从长到短排序,优先匹配多字符符号 const sortedSigns = [...signs].sort((a, b) => b.length - a.length); // 转义正则特殊字符的工具函数 function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } // 构建匹配模式:捕获符号前后的空格,以及符号本身 const pattern = new RegExp(`(\\s*)(${sortedSigns.map(escapeRegExp).join('|')})(\\s*)`, 'g'); // 处理输入文本的函数 function wrapSigns(input) { return input.replace(pattern, (_, preSpace, sign, postSpace) => { // 补充前空格:如果原本没有则加一个 const prefix = preSpace ? preSpace : ' '; // 补充后空格:如果原本没有则加一个 const suffix = postSpace ? postSpace : ' '; return `${prefix}^${sign}^${suffix}`; }).trim(); // 移除首尾可能多出的空格 } // 测试示例 const input = 'this is, a text?'; console.log(wrapSigns(input)); // 输出: 'this is ^,^ a text ^?^'
关键细节说明
- 排序逻辑:必须按长度降序排列符号数组,确保
!!、...这类多字符符号先被匹配,避免拆分。 - 空格处理:通过正则的捕获组获取符号前后的空格状态,自动补充缺失的空格,完全符合需求中的格式要求。
- 转义处理:
escapeRegExp函数确保所有符号都能被正则准确识别,不会因为特殊字符导致匹配失效。
内容的提问来源于stack exchange,提问作者Sara Ree
相关产品推荐
相关产品推荐

