Ответ 1
Здесь new RegExp(string, flags)
где flags
- g
или i
. Так
'GODzilla'.replace( new RegExp('god', 'i'), '' )
оценивается как
zilla
Скажем, я хотел сделать следующее повторно используемое:
function replace_foo(target, replacement) {
return target.replace("string_to_replace",replacement);
}
Я мог бы сделать что-то вроде этого:
function replace_foo(target, string_to_replace, replacement) {
return target.replace(string_to_replace,replacement);
}
С строковыми литералами это достаточно просто. Но что, если я хочу получить немного более сложное с регулярным выражением? Например, я хочу заменить все, кроме string_to_replace
. В инстинктивно я бы попытался расширить это, сделав что-то вроде:
function replace_foo(target, string_to_replace, replacement) {
return target.replace(/^string_to_replace/,replacement);
}
Это не работает. Я предполагаю, что он считает, что string_to_replace
является строковым литералом, а не переменной, представляющей строку. Можно ли создавать регулярные выражения JavaScript "на лету" с помощью строковых переменных? Что-то вроде этого было бы здорово, если это вообще возможно:
function replace_foo(target, string_to_replace, replacement) {
var regex = "/^" + string_to_replace + "/";
return target.replace(regex,replacement);
}
Здесь new RegExp(string, flags)
где flags
- g
или i
. Так
'GODzilla'.replace( new RegExp('god', 'i'), '' )
оценивается как
zilla
С строковыми литералами это достаточно просто.
Не совсем! Этот пример заменяет первое появление 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, '$$$$');
}
(Четыре $
, потому что это сама замена string-argh!)
Теперь вы можете реализовать глобальную замену строк с помощью 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)
... и все. Это общепринятая идиома.
say Я хочу заменить все, кроме 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);
Как говорили другие, используйте new RegExp(pattern, flags)
для этого. Стоит отметить, что вы передадите строковые литералы в этот конструктор, поэтому каждая обратная косая черта должна быть экранирована. Если, например, вы хотели, чтобы ваше регулярное выражение соответствовало обратному косую черту, вам нужно сказать new RegExp('\\\\')
, тогда как литерал регулярного выражения должен быть только /\\/
. В зависимости от того, как вы собираетесь использовать это, вы должны быть осторожны с передачей пользовательского ввода такой функции без надлежащей предварительной обработки (экранирование специальных символов и т.д.). Без этого ваши пользователи могут получить некоторые очень неожиданные результаты.
Да, вы можете.
https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
function replace_foo(target, string_to_replace, replacement) {
var regex = new RegExp("^" + string_to_replace);
return target.replace(regex, replacement);
}
Я думаю, что у меня есть очень хороший пример для выделения текста в строке (он не ищет регистр, но выделяется с использованием регистра)
function getHighlightedText(basicString, filterString) {
if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString;
return basicString.replace(new RegExp(filterString.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&'), 'gi'),
function(match)
{return "<mark>"+match+"</mark>"});
}