给定字符串,我如何用数组中的多个单词替换某些单词?

时间:2019-02-17 21:23:11

标签: javascript arrays regex array-splice

假设我有一个句子和一系列单词:

let sentence = 'My * is * years old.';
let words = ['dog', 3];

//expected result => My dog is 9 years old.

如何在给定数组中用适当的单词替换每个星号(*)? 但是我们也要说,在某些情况下,星号比数组中的元素更多:

let sentence = 'The soldiers marched *, *, *, *.';
let words = ['left', 'right'];

//expected result => The soldiers marched left, right, left, right.

使用正则表达式是解决此问题的唯一方法,还是有通用的JS解决方案?

5 个答案:

答案 0 :(得分:3)

您可以使用一个替换函数,该函数的起始索引具有附加值,该索引的默认值为零。

要使索引保持在有效范围内,可以使用remainder operator %和数组的长度。

const
    replace = (string, array, i = 0) =>
        string.replace(/\*/g, _=> array[i++ % array.length]);

console.log(replace('My * is * years old.', ['dog', 3]));
console.log(replace('The soldiers marched *, *, *, *.', ['left', 'right']));

答案 1 :(得分:0)

let sentence = 'My * is * years old.';
let words = ['dog', 3];
let count =0;
while (sentence.indexOf('*') > -1) {
    sentence = sentence.replace('*', words[count++]);
    if (count >= words.length) count = 0;
}
console.log(sentence);

显示:“我的狗三岁了。”

答案 2 :(得分:0)

如果您真的不喜欢正则表达式,可以这样做:

words = ["left", "right"];
"The soldiers marched *, *, *, *.".split("*").map(function (x, i) {
  return i === 0 ? x : words[(i + 1) % words.length] + x;
}).join("");

执行轨迹:

init  | "The soldiers marched *, *, *, *."
split | ["The soldiers marched ", ", ", ", ", ", ", "."]
i = 0 | ["The soldiers marched ", ", ", ", ", ", ", "."]
i = 1 | ["The soldiers marched ", "left, ", ", ", ", ", "."]
i = 2 | ["The soldiers marched ", "left, ", "right, ", ", ", "."]
i = 3 | ["The soldiers marched ", "left, ", "right, ", "left, ", "."]
i = 4 | ["The soldiers marched ", "left, ", "right, ", "left, ", "right."]
join  | "The soldiers marched left, right, left, right."

答案 3 :(得分:0)

另一个正则表达式免费选项:

pandoc --filter pandoc-citeproc default.yaml meta.md outline.md -o outline.pdf
s = "The soldiers marched *, *, *, *.";
f = Function("words", "var i = 0; return \"" + s.split("*").join(
  "\" + words[(i++) % words.length] + \""
) + "\";");

尽管提防恶意代码:

> | f(["L", "R"])
< | "The soldiers marched L, R, L, R."
> | f(["L", "R"].reverse())
< | "The soldiers marched R, L, R, L."
> | f(["L", "R", "R"])
< | "The soldiers marched L, R, R, L."
s = "The soldiers marched *, *, *, *.";
s = "\", console.log(\"VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!\"), \"" + s;
f = Function("words", "var i = 0; return \"" + s.split("*").join(
  "\" + words[(i++) % words.length] + \""
) + "\";");

您应该始终清除输入内容:

> | f(["L", "R"])
  | VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!
< | "The soldiers marched L, R, L, R."
s = "The soldiers marched *, *, *, *.";
s = "\", alert(\"VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!\"), \"" + s;
s = s.split("\"").join("\\\""); // potentially not sufficient!
f = Function("words", "var i = 0; return \"" + s.split("*").join(
  "\" + words[(i++) % words.length] + \""
) + "\";");

但是我不敢相信这是防弹的:-|

答案 4 :(得分:0)

一个字符接一个字符:

input = "The soldiers marched *, *, *, *.";
words = ["left", "right"];
output= ""
for (i = 0, j = 0; i < input.length; i++) {
  output += input[i] !== "*" ? input[i] : (
    words[(j++) % words.length]
  );
}
console.log(output)

如您所见,正则表达式有多种选择。无论如何,您真正需要了解的是余数运算符(%):

0 % 2 = 0 | 0 -> 0
1 % 2 = 1 | 1 -> 1
2 % 2 = 0 | 2 -> 0
3 % 2 = 1 | 3 -> 1
4 % 2 = 0 | 4 -> 0

0,1,0,1,0,1,...有吗?结果永远不会到达正确的操作数。当您需要多次遍历同一数组时,此功能特别有用:

abc = ["A", "B", "C"]
for (i = 0; i < 2 * abc.length; i++) {
  // j will never reach abc.length
  j = i % abc.length; // 0, 1, 2, 0, ...
  console.log(i, j, abc[j]);
}