You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则表达式为指定数组符号添加^包裹并补空格?

问题描述

需要将指定数组中的每个符号用^包裹,示例如下:

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();
        }
    }
正则表达式实现方案

核心思路

  1. 优先匹配长符号:避免短符号拆分长符号(比如先匹配!会把!!拆成两个单独的!),所以先对符号数组按长度从长到短排序。
  2. 转义正则特殊字符:.、?等符号是正则保留字符,必须转义后才能准确匹配。
  3. 处理空格:捕获符号前后的空格,自动补充缺失的空格,保证符号与单词间有分隔。

完整代码实现

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:45:44