Подтвердить что ты не робот

Как узнать, что JavaScript string.replace() сделал что-нибудь?

Функция replace возвращает новую строку с заменой, но если не было никаких слов для замены, возвращается исходная строка. Есть ли способ узнать, действительно ли это заменило что-либо отдельно от сравнения результата с исходной строкой?

4b9b3361

Ответ 1

Простой вариант - проверить совпадения перед заменой:

var regex = /i/g;
var newStr = str;

var replaced = str.search(regex) >= 0;
if(replaced){
    newStr = newStr.replace(regex, '!');
}

Если вы этого не хотите, вы можете злоупотреблять обратным вызовом replace, чтобы добиться этого за один проход:

var replaced = false;
var newStr = str.replace(/i/g, function(token){replaced = true; return '!';});

Ответ 2

Сравнение строк до и после - самый простой способ проверить, не сделал ли он что-либо, в String.replace() нет встроенной поддержки.

[надуманный пример того, как '==' может быть удалён, потому что это было неправильно]

Ответ 3

Если ваша замена имеет другую длину от искомого текста, вы можете проверить длину строки до и после. Я знаю, это частичный ответ, действительный только для подмножества проблемы.

ИЛИ

Вы можете выполнить поиск. Если поиск удался, вы замените на подстроке, начиная с найденного индекса, а затем перекомпоновите строку. Это может быть медленнее, потому что вы генерируете 3 строки вместо 2.

var test = "Hellllo";
var index = test.search(/ll/);

if (index >= 0) {
    test = test.substr(0, index - 1) + test.substr(index).replace(/ll/g, "tt");
}

alert(test);

Ответ 4

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

Ответ 5

С помощью indexOf вы можете проверить, содержит ли строка строку. Похоже, вы можете использовать это.

Ответ 6

посмотрите на string.match() или string.search()

Ответ 7

Javascript replace отклоняется дизайном. Зачем? Он не совместим с заменой строки в обратном вызове.

Например:

"ab".replace(/(a)(b)/, "$1$2")
> "ab"

Мы хотим проверить, что замена выполняется за один проход. Я представлял себе что-то вроде:

"ab".replace(/(a)(b)/, "$1$2", function replacing() { console.log('ok'); })
> "ab"

Реальный вариант:

"ab".replace(/(a)(b)/, function replacing() {
  console.log('ok');
  return "$1$2";
})

> ok
> "$1$2"

Но функция replacing предназначена для приема $0, $1, $2, offset, string, и нам нужно бороться с заменой "$ 1 $2". Решение:

"ab".replace(/(a)(b)/, function replacing() {
  console.log('ok');
  // arguments are $0, $1, ..., offset, string
  return Array.from(arguments).slice(1, -2)
  .reduce(function (pattern, match, index) {
    // '$1' from strings like '$11 $12' shouldn't be replaced.
    return pattern.replace(
      new RegExp("\\$" + (index + 1) + "(?=[^\\d]|$)", "g"),
      match
    );
  }, "$1$2");
});

> ok
> "ab"

Это решение не идеально. Сама замена строки имеет свои собственные WAT. Например:

"a".replace(/(a)/, "$01")
> "a"

"a".replace(/(a)/, "$001")
> "$001"

Если вы хотите заботиться о совместимости, вы должны прочитать spec и реализовать все свое безумие.