替换文本但不包含特定字符?
Replace text but not if contain specific characters?
在 JavaScript 中,我使用以下代码替换与特定字符串匹配的文本。替换像这样包装字符串:"A(hello)"
。它工作得很好,但如果有两个相同的字符串,例如:"Hello hi Hello"
,只有第一个会被标记,如果我尝试两次,它将被标记为双倍,如下所示:"A(A(Hello)) Hi Hello"
].
一个解决方案是不替换包含 "A("
或介于 "A("
和 ")"
之间的单词;两者都可以。
知道如何实现吗?
注意:我不能使用replaceAll,因为如果已经有一个词被替换,然后添加一个新词,那么第一个将被覆盖。因此我需要一个像上面那样的解决方案。例如,如果我有一个字符串说“Hello hi”,我标记了 Hello,它会说“A(Hello) hi”,但是如果我再次将 Hello 添加到文本中并替换它,它将看起来像这样: A(A(Hello)) hi A(Hello)
.
这是我目前得到的:
let text = "Hello hi Hello!"
let selection = "Hello"
let A = `A(${selection})`
let addWoman = text.replace(selection, A)
A solution to this could be to not replace a word if it contains "A(" or is between "A(" and ")"; both would work.
为了避免在 A(...)
字符串 中重新匹配 selection
,您可以匹配 A(...)
并将其捕获到一个组中,以便要知道该组是否匹配,应该保留它,否则,匹配您选择的单词:
let text = "Hello hi Hello!"
let selection = "Hello"
let A = `A(${selection})`
const rx = new RegExp(String.raw`(A\([^()]*\))|${selection.replace(/[-\/\^$*+?.()|[\]{}]/g, '\$&')}`, 'g')
let addWoman = text.replace(rx, (x,y) => y || A)
console.log(addWoman);
// Replacing the second time does not modify the string:
console.log(addWoman.replace(rx, (x,y) => y || A))
正则表达式看起来像 /(A\([^()]*\))|Hello/g
,它匹配
(A\([^()]*\))
- 第 1 组:A
,然后是 (
,后跟 (
和 )
以外的零个或多个字符,然后是 )
字符
|
- 或
Hello
- Hello
字符串。
如果我们在完整单词 Hello
之前 A(
:
,您可以在匹配失败的模式中使用否定前瞻断言
(?<!A\()\bHello\b
并替换为A($&)
代码:
let text = "Hello hi Hello!";
let selection = "Hello";
let A = `A(${selection})`;
let re = new RegExp(`(?<!A\()\b${selection}\b`, "g");
let addWoman = text.replace(re, A);
console.log(addWoman);
console.log(addWoman.replace(re, A));
在 JavaScript 中,我使用以下代码替换与特定字符串匹配的文本。替换像这样包装字符串:"A(hello)"
。它工作得很好,但如果有两个相同的字符串,例如:"Hello hi Hello"
,只有第一个会被标记,如果我尝试两次,它将被标记为双倍,如下所示:"A(A(Hello)) Hi Hello"
].
一个解决方案是不替换包含 "A("
或介于 "A("
和 ")"
之间的单词;两者都可以。
知道如何实现吗?
注意:我不能使用replaceAll,因为如果已经有一个词被替换,然后添加一个新词,那么第一个将被覆盖。因此我需要一个像上面那样的解决方案。例如,如果我有一个字符串说“Hello hi”,我标记了 Hello,它会说“A(Hello) hi”,但是如果我再次将 Hello 添加到文本中并替换它,它将看起来像这样: A(A(Hello)) hi A(Hello)
.
这是我目前得到的:
let text = "Hello hi Hello!"
let selection = "Hello"
let A = `A(${selection})`
let addWoman = text.replace(selection, A)
A solution to this could be to not replace a word if it contains "A(" or is between "A(" and ")"; both would work.
为了避免在 A(...)
字符串 中重新匹配 selection
,您可以匹配 A(...)
并将其捕获到一个组中,以便要知道该组是否匹配,应该保留它,否则,匹配您选择的单词:
let text = "Hello hi Hello!"
let selection = "Hello"
let A = `A(${selection})`
const rx = new RegExp(String.raw`(A\([^()]*\))|${selection.replace(/[-\/\^$*+?.()|[\]{}]/g, '\$&')}`, 'g')
let addWoman = text.replace(rx, (x,y) => y || A)
console.log(addWoman);
// Replacing the second time does not modify the string:
console.log(addWoman.replace(rx, (x,y) => y || A))
正则表达式看起来像 /(A\([^()]*\))|Hello/g
,它匹配
(A\([^()]*\))
- 第 1 组:A
,然后是(
,后跟(
和)
以外的零个或多个字符,然后是)
字符|
- 或Hello
-Hello
字符串。
如果我们在完整单词 Hello
之前 A(
:
(?<!A\()\bHello\b
并替换为A($&)
代码:
let text = "Hello hi Hello!";
let selection = "Hello";
let A = `A(${selection})`;
let re = new RegExp(`(?<!A\()\b${selection}\b`, "g");
let addWoman = text.replace(re, A);
console.log(addWoman);
console.log(addWoman.replace(re, A));