2015-02-26 3 views
0

Возможно ли, без потери производительности, заменить все вхождения подстроки на другую строку и полностью избежать использования RegExp на этом пути? То есть удалите RegExp из уравнения, просто чтобы убедиться, что волшебство RegExp не происходит, когда вы забываете правильно сбежать от чего-то вроде +.Заменить все вхождения в строке и избежать escape-кода RegExp

'1+1 2+2'.replace('+', '-') -> only first "+" is replaced 
'1+1 2+2'.replace(/\+/g, '-') -> undesired regexp complexities 

UPDATE 1

Это не решает проблему побега:

String.prototype.replaceAll= function(search, replace) { 
    return this.replace(new RegExp(search, "g"), replace); 
} 

UPDATE 2

Выполнение программного экранирования в это падение производительности:

RegExp.quote = function(str) { 
    return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); 
}; 
+0

Комментарии для расширенного обсуждения; этот разговор был [перемещен в чат] (http://chat.stackoverflow.com/rooms/71788/discussion-on-question-by-exebook-replace-all-occurrences-in--string-and-avoid) , –

ответ

1
function replaceAll(str, search, replace) { 
    while (str.indexOf(search) > -1) { 
     str = str.replace(search, replace); 
    } 
    return str; 
} 

Это работает. Однако, более результативно, используя регулярное выражение? Давай попробуем.

Вот функция регулярного выражения Я протестированные против:

function replaceAllRegex(str, search, replace) { 
    return str.replace(new RegExp(search.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"), 'g'), replace); 
} 

Согласно jsperf, не-регулярных выражений версии делает ~ 8k OPS/сек, в то время как регулярное выражение версия делает ~ 123K OPS/сек. При автоматическом удалении символов.

Вы должны просмотреть свое мнение о том, что «побег - это удар по производительности».

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

PS: Roel's version может быть быстрее, чем регулярное выражение.

+0

Ручная смена не занимает много времени (я имею в виду, что это занимает время, а не время процессора). Но программный unescape, очевидно, занимает некоторое процессорное время. – exebook

+0

Вот те же тестовые примеры **, но в том числе программные экранирование **: http://jsperf.com/replaceall-regex-or-not/2 –

+0

'while (replace)' все еще на 32% медленнее для меня. Интересно, нужен ли 'indexOf()'. Есть ли способ узнать, действительно ли 'replace()' что-то сделал? – exebook

3

В качестве альтернативы, на основе коды и тест Флориана Margaine в:

window.replaceQuick = function(subject, search, replace) { 
     var index = -1, offset = 0; 
     var result = ''; 
     while ((index = subject.indexOf(search, offset)) !== -1) { 
     result += subject.substring(offset, index) + replace; 
     offset = index + search.length; 
     } 
     return result + search.substring(offset); 
    } 

Поскольку я делаю частичную экстракцию он должен получить более высокую производительность.

http://jsperf.com/replaceall-regex-or-not/3

+0

Хорошая точка, все же зависит от варианта использования и времени исполнения. Но обычно регулярное выражение лучше. Но, как мы упоминали ранее, преждевременная оптимизация. –

+0

Плюс один, потому что да ... ваша реализация в некоторых случаях быстрее (и, как заметил Флориан, в перфомансе была ошибка) –

+2

Эта предлагаемая функция replaceQuick, вероятно, самая лучшая способ сделать это без RegExp, поэтому в этом смысле он лучше отвечает на вопрос OP. Но если вы не знаете, что вы работаете на медленном движке RegExp * и *, что влияние производительности действительно имеет значение, зачем беспокоиться? RegExp, вероятно, будет быстрее, если вы проверите все браузеры и используете различные реальные данные. – Brandin

Смежные вопросы