Со строковыми литералами это достаточно просто.
На самом деле, нет! Пример заменяет только первое вхождение string_to_replace
. Чаще всего вы хотите заменить все вхождения, в этом случае вам нужно преобразовать строку в глобальный ( /.../g
) RegExp. Вы можете сделать это из строки, используя new RegExp
конструктор:
new RegExp(string_to_replace, 'g')
Проблема в том, что любые специальные символы регулярных выражений в строковом литерале будут вести себя по-своему, а не как обычные символы. Вы должны были бы их убрать, чтобы это исправить. К сожалению, для этого нет встроенной функции, поэтому вы можете использовать ее:
function escapeRegExp(s) {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}
Также обратите внимание, что когда вы используете RegExp replace()
, строка замены теперь также имеет специальный символ $
. Этого также необходимо избежать, если вы хотите, чтобы $
в вашем тексте замены был литерал !
function escapeSubstitute(s) {
return s.replace(/\$/g, '$$$$');
}
(Четыре $
с, потому что это сама строка замены - аааа!)
Теперь вы можете реализовать глобальную замену строк с помощью RegExp:
function replace_foo(target, string_to_replace, replacement) {
var relit= escapeRegExp(string_to_replace);
var sub= escapeSubstitute(replacement);
var re= new RegExp(relit, 'g');
return target.replace(re, sub);
}
Вот это боль. К счастью, если все, что вам нужно, это заменить строку без дополнительных частей регулярного выражения, есть более быстрый способ:
s.split(string_to_replace).join(replacement)
...и это все. Это общепринятая идиома.
говорят, что я хочу заменить все, кроме string_to_replace
Что это значит, вы хотите заменить все фрагменты текста, не участвуя в сопоставлении со строкой? Замена на ^
определенно не делает этого, потому что ^
означает токен начала строки, а не отрицание. ^
это только отрицание в []
группах персонажей. Есть и негативные перспективы (?!...)
, но в JScript есть проблемы с этим, поэтому вам следует избегать этого.
Вы можете попробовать сопоставить строку «все до» и использовать функцию, чтобы отбросить любое пустое натяжение между совпадающими строками:
var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')')
return target.replace(re, function(match) {
return match[1]===''? match[2] : replacement+match[2];
});
Здесь, опять же, разделение может быть проще:
var parts= target.split(string_to_match);
for (var i= parts.length; i-->0;)
if (parts[i]!=='')
parts[i]= replacement;
return parts.join(string_to_match);
/
разделители регулярных выражений при использовании этой формы тоже.