如何从字符串中移除指定字符,并在后续需要时将其精准放回原始位置
字符串移除指定字符后按原位置还原的可落地实现
核心逻辑非常直接:从执行移除操作的第一步开始,就完整留存被移除字符的位置元数据,绝不能只留一个无空格的裸字符串后续瞎猜位置,没有这个元数据,任何还原操作都是不准的。
具体实现步骤
- 移除时同步记录位置
不要直接调用replace(/ /g, "")生成无空格字符串就完事,遍历原始字符串时同步把两类信息拆分开存:- 把所有非目标移除字符的内容拼接成纯内容片段,作为后续修改的基础文本
- 把每一个被移除的指定字符在原字符串中的索引,按顺序存在一个独立数组里
以示例的"This is my string"为例,遍历后会得到: - 纯内容片段:
Thisismystring - 被移除的空格位置数组:
[4, 7, 10]
- 对纯内容片段执行任意修改
只要修改过程中没有打乱纯内容的字符顺序、没有对单字符做拆分/合并,不管你是给每个字符加括号、替换内容、做格式调整,都不影响后续的位置还原。比如把纯内容改成示例要求的"(T)(h)(i)(s)(i)(s)(m)(y)(s)(t)(r)(i)(n)(g)",本质还是13个顺序不变的独立字符,只是每个字符从1个长度变成了3个长度。 - 反向计算插入位置完成还原
从位置数组的最后一个元素往前遍历插入,避免前面的插入操作打乱后续的索引偏移:- 对每个被移除的字符,计算它前面一共对应多少个纯内容里的有效字符:原字符位置减去它前面已经被移除的同类型字符数量
- 结合修改后单个纯内容字符的实际长度,算出当前要插入的准确索引
- 把移除的字符插入到计算好的位置即可
完整可运行示例代码
// 1. 原始字符串与初始化存储 const originalStr = "This is my string"; const removedCharPositions = []; let pureContent = ""; // 2. 遍历拆分内容+记录位置 for (let i = 0; i < originalStr.length; i++) { const currentChar = originalStr[i]; if (currentChar === " ") { removedCharPositions.push(i); } else { pureContent += currentChar; } } // 3. 对纯内容做自定义修改(示例为每个字符加括号) const modifiedContent = pureContent.split("").map(c => `(${c})`).join(""); // 4. 计算还原所需的单字符长度 const singleCharLength = modifiedContent.length / pureContent.length; let finalResult = modifiedContent; // 5. 从后往前插入还原空格 for (let i = removedCharPositions.length - 1; i >= 0; i--) { const validPureCharCount = removedCharPositions[i] - i; const insertPos = validPureCharCount * singleCharLength; finalResult = finalResult.slice(0, insertPos) + " " + finalResult.slice(insertPos); } // 最终输出为 "(T)(h)(i)(s) (i)(s) (m)(y) (s)(t)(r)(i)(n)(g)"
常见踩坑提醒
- 如果纯内容修改过程中打乱了字符顺序、增删了核心字符数量,之前留存的位置元数据会完全失效,这种场景下是不可能做到精准还原的
- 插入位置时尽量从后往前操作,省去额外计算偏移量的步骤,代码更不容易出bug
- 不依赖正则匹配去反向找空格位置,所有位置判断都基于你最开始存的元数据,精准度是100%的
内容的提问来源于stack exchange,提问作者Kamran Adil
相关产品推荐
相关产品推荐

