По заданной строке, как заменить определенные слова несколькими словами в массиве? - PullRequest
0 голосов
/ 18 февраля 2019

Допустим, у меня есть предложение и массив слов:

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 голосов
/ 18 февраля 2019

Один символ за другим:

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]);
}
0 голосов
/ 18 февраля 2019

Еще одна опция без регулярных выражений:

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

Но я бы не рискнул, что это пуленепробиваемое: - |

0 голосов
/ 18 февраля 2019

Вы можете использовать функцию замены с дополнительным значением для начального индекса, значение которого по умолчанию равно нулю.

Чтобы сохранить индекс в допустимом диапазоне, вы можете воспользоваться оператором остатка % с длиной массива.

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']));
0 голосов
/ 18 февраля 2019

Если вам действительно не нравятся регулярные выражения, вы можете сделать это:

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."
0 голосов
/ 18 февраля 2019

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 года».

...