【问题标题】:javascript - string replacement, replace "^" with "" and "^^" with "^"javascript - 字符串替换,将“^”替换为“”,将“^^”替换为“^”
【发布时间】:2026-02-21 15:15:01
【问题描述】:

删除 JavaScript 中的临时转义字符...

基本示例:

我有以下字符串:

"[x^::^^y]"

输出应该是:

"[x::^y]"

基本上,任何与另一个^ 不相邻的^ 都应被删除,^^ 的任何出现都应替换为^

更多示例:

.parse("[^^x:^y^:^^^^^^]") // output: "[^x:y:^^^]"
.parse("[^x:^^^^y^^^z]") // output: "[x:^^y^z]"

它将成为我正在开发的 JSON 替代方案的解析脚本的一部分,以期减少内部存储文件的文件大小。

【问题讨论】:

  • 如果你想要一个更紧凑的 JSON 替代方案,我可以建议protocol buffers吗?
  • @PatrickRoberts 并没有真正回答我的问题,但感谢您的建议。我会再调查一下。
  • 尝试替换("^","").replace("^^","^")
  • @ArunKumarMN 之所以有效,是因为每次调用只替换第一次出现的搜索字符串...
  • 这可能有效str.replace(/\^+/g, m => m.length % 2 ? '' : '^')

标签: javascript regex replace


【解决方案1】:

我会使用 .replace() 和这样的替换函数:

function parse (str) {
  return str.replace(/\^{1,2}/g, s => s.slice(1));
}

console.log(parse('[x^::^^y]'));
console.log(parse('[^^x:^y^:^^^^^^]'));
console.log(parse('[^x:^^^^y^^^z]'));

【讨论】:

  • 我是一名自学成才的 JS 开发人员,已经编写了 3 年的代码……甚至不知道它的存在。我在从事的每个项目中都学到了一些新东西。
【解决方案2】:

还有一个想法:Capture 一对^$1 或不捕获其余的和replace with $1

function parse (s) {
  return s.replace(/(\^)\^|\^/g, '$1');
}

console.log(parse('[^x:^^^^y^^^z]'));

@PatrickRoberts 评论:模式可以进一步简化为:\^(\^?)

【讨论】:

  • 不错的发现!顺便说一句,/(\^?)\^/g 也可以与 $1 替换器一起使用。
  • @PatrickRoberts 非常好,谢谢!我注意到它可能会更慢,但换成\^(\^?) 甚至会是最快的。
【解决方案3】:

由于替换调用将作用于整个字符串,因此两个替换如果一个接一个地执行,将相互干扰。无论调用替换的顺序如何,这总是会导致错误的结果。

解决这个问题的唯一方法是使用中间状态。例如,如果我们使用 + 作为中间符号,它会是这样的:

  1. 将 ^^ 替换为 +,
  2. 接着用空字符串替换^,
  3. 然后,将 + 替换为 ^

显然 + 符号可能出现在原始字符串本身中,因此您需要选择一个不会出现在原始字符串中的更好的中间符号。它可以是多字符甚至是控制字符。

编辑:使用替换函数的公认答案是 JS 更好的方法。我把这个答案留在这里,以防有人偶然发现这个问题,在其他语言中出现类似问题,而替换函数不可用。

【讨论】:

  • 用其他语言重新创建替换函数技术在技术上是可行的。
  • 是的,只要有正则表达式引擎,就应该可以创建这样的实用方法。根据输入大小,甚至可能是个好主意。只是在某些语言中这样做会很麻烦。尤其是那些没有 lambda 的。
  • 似乎有了lookbehind 能力,它可以执行两个连续的替换。即使有这样的规定,你的答案也被否定了。
【解决方案4】:

上面的答案很好!!

但另一种可能的方式是使用前瞻和后瞻。

function replace_carets(mystring) {
  return mystring
    .replace(/(?<!\^)(\^{2})*\^(?!\^)/g, "$1") //removes isolated ^ or last odd numbered ^
    .replace(/\^{2}/g, "^"); //replaces ^^ with ^
}
console.log(replace_carets("[x^::^^y]"));
console.log(replace_carets("[^^x:^y^:^^^^^^]"));
console.log(replace_carets("[^x:^^^^y^^^z]"));

远非优雅,但我挑战自己做这件事,所以与你分享。

【讨论】:

  • 真的吗?当我单击“运行代码 sn-p”时,我没有看到任何错误。你可以看看这里codepen.io/irfan/pen/gNmQBm
  • 代码 sn-p 适用于 Chrome,但不适用于 FF 和 Edge。
  • 所以除了chrome之外的浏览器似乎不支持lookbehinds。所以不是推荐的解决方案。
  • 您可以通过从一组或多对 (*) 而不是一组或多对 (+) 中删除最后一个奇数编号 ^ 来简化您的解决方案:@ 987654326@