2016-05-12 1 views
12

Исходя из других языков программирования, String.replace() обычно заменяет все вхождения совпадающих строк. Однако это не относится к javascript/typescript. Я нашел несколько решений в Интернете с javascript с использованием регулярных выражений. У меня сразу возникли проблемы с этим решением из-за специальных символов. Я подозреваю, что есть способ исправить это с помощью регулярного выражения, но я не специалист по регулярному выражению. Как многие из них сделали передо мной, я создал свой собственный метод.В машинописном тексте String.Replace заменяет только первое совпадение строки. Need String.replaceAll()

Возможно, есть способы улучшить производительность, используя специальный класс StringBuilder(). Я приветствую любые мысли.

public static Replace = function (originalString: string, oldValue: string, newValue: string, ignoreCase: boolean = false) { 
    // 
    // if invalid data, return the original string 
    // 
    if ((originalString == null) || (oldValue == null) || (newValue == null) || (oldValue.length == 0)) 
     return (originalString); 
    // 
    // do text replacement 
    // 
    var dest = "";   
    var source: string = originalString; 
    if (ignoreCase) 
    { 
     source = source.toLocaleLowerCase(); 
     oldValue = oldValue.toLowerCase(); 
    } 
    // 
    // find first match 
    // 
    var StartPos = 0; 
    var EndPos = source.indexOf(oldValue, StartPos); 
    var Skip = (EndPos >= 0) ? EndPos - StartPos : source.length-StartPos; 
    // 
    // while we found a matched string 
    //  
    while (EndPos > -1) { 
     // 
     // copy original string skipped segment 
     // 
     if (Skip > 0) dest += originalString.substr(StartPos, Skip);    
     // 
     // copy new value 
     // 
     dest += newValue; 
     // 
     // skip over old value 
     // 
     StartPos = EndPos + oldValue.length; 
     // 
     // find next match 
     // 
     EndPos = source.indexOf(oldValue, StartPos); 
     Skip = (EndPos >= 0) ? EndPos - StartPos : source.length - StartPos;  
    } 
    // 
    // append the last skipped string segment from original string 
    // 
    if (Skip > 0) dest += originalString.substr(StartPos, Skip); 

    return dest; 
} 

Для того, чтобы добавить поддержку этого метода к классу string я добавил следующий код:

interface String { EZReplace(oldValue: string, newValue: string, ignorCase?: boolean): string; } 

String.prototype.EZReplace = function (oldValue: string, newValue: string, ignorCase: boolean = false) { 
return EZUtil.Replace(this, oldValue, newValue, ignorCase);} 

.... После повторного просмотра других сообщений, я изменил код, чтобы использовать регулярные выражения. Было бы интересно выполнить тесты производительности.

public static Replace = function (originalString: string, oldValue: string, newValue: string, ignoreCase: boolean = false) { 
    // 
    // if invalid data, return the original string 
    // 
    if ((originalString == null) || (oldValue == null) || (newValue == null) || (oldValue.length == 0)) 
     return (originalString); 
    // 
    // set search/replace flags 
    // 
    var Flags: string = (ignoreCase) ? "gi" : "g"; 
    // 
    // apply regex escape sequence on pattern (oldValue) 
    // 
    var pattern = oldValue.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 
    // 
    // replace oldValue with newValue 
    // 
    var str = originalString.replace(new RegExp(pattern, Flags), newValue); 
    return (str); 
} 
+2

Вы уже проверили этот пост? http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript – Patricia

+0

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

ответ

21

В машинописи, String.Replace заменяет только первое вхождение найденной строки. Need String.replaceAll() method

Здесь нет ничего особенного в TypeScript (after all TypeScript is just JavaScript with type annotations). JavaScript string.replace заменяет только первый экземпляр, если задана строка. Единственный способ заменить все - использовать regex с модификатором /g.

В качестве альтернативы я просто:

somestring.split('oldString').join('newString'); 
+0

Да, метод String.split(). Join() является коротким и сладким. Однако невозможно выполнить поиск/замену без учета регистра. В первый раз, когда я использовал регулярное выражение с модификатором/g, он сгенерировал недопустимый шаблон для регулярного выражения во время выполнения кода. Мне нужно было включить escape-последовательности в шаблон. 'var pattern = oldValue.replace (/ [- \ [\] \/\ {\} \ (\) \ * \ + \? \. \\\^\ $ \ \]/g," \\ $ &"); ' Вот почему я хотел бы включить всю функцию в свой пример. Процедура проста и достаточно коротка, чтобы позволить. –

+0

Любовь, которая разделяет соединение! – Drutten

+2

Как ссылка, здесь вызов замены TypeScript с использованием регулярного выражения: 'myString.replace (/ oldString/g, 'newString);' – Thomas