【问题标题】:Given string how do I replace certain words with multiple words in an array?给定字符串如何用数组中的多个单词替换某些单词?
【发布时间】:2019-02-17 21:23:10
【问题描述】:

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

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 解决方案?

【问题讨论】:

  • 你有尝试过什么吗?是的,使用 vanilla js 是可能的。
  • 正则表达式是js内置的,所以是vanilla js。您想出了什么使用正则表达式的解决方案?可以重新调整它的用途,使其不使用正则表达式。
  • 以后,请不要在不符合您的问题的问题上添加标签。我删除了函数式编程标签,因为这与函数式编程无关。您可以将鼠标悬停在标签上以获取其内容的简短描述。了解该网站的许多常规用户都遵循某些标签,对于弹出的与我们的兴趣无关的问题,我们可能会有些脾气暴躁。其次,更不重要的是,正则表达式 vanilla js :)

标签: javascript arrays regex array-splice


【解决方案1】:

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

为了使索引保持在有效范围内,您可以将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']));

【讨论】:

  • 我正在考虑从索引的偏移量开始。 (除了必要变量的声明和初始化。)
【解决方案2】:

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);

显示:“我的狗 3 岁。”

【讨论】:

    【解决方案3】:

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

    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."
    

    【讨论】:

      【解决方案4】:

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

      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] + \""
      ) + "\";");
      
      > | f(["L", "R"])
      < | "", alert("VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!"), "The soldiers marched L, R, L, R."
      

      但我不敢说它是防弹的:-|

      【讨论】:

        【解决方案5】:

        一个接一个的字符:

        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]);
        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-11-03
          • 1970-01-01
          • 1970-01-01
          • 2020-08-19
          • 2021-06-30
          • 1970-01-01
          • 2022-01-17
          相关资源
          最近更新 更多