Заменить несколько символов в одном вызове замены

258

Очень простой маленький вопрос, но я не совсем понимаю, как это сделать.

Мне нужно заменить каждый экземпляр «_» на пробел, а каждый экземпляр «#» - пустым или пустым.

var string = '#Please send_an_information_pack_to_the_following_address:';

Я пробовал это:

string.replace('#','').replace('_', ' ');

Мне не очень нравятся подобные команды. Есть ли другой способ сделать это в одном?

Шеннон Хохкинс
источник
См. Ответ на этот вопрос: stackoverflow.com/questions/7072330/…
DeweyOx

Ответы:

517

Используйте оператор ИЛИ ( |):

var str = '#this #is__ __#a test###__';
str.replace(/#|_/g,''); // result: "this is a test"

Вы также можете использовать класс символов:

str.replace(/[#_]/g,'');

скрипка

Если вы хотите заменить хеш с одной вещью, а подчеркивание - с другой, то вам просто придётся соединиться. Тем не менее, вы можете добавить прототип:

String.prototype.allReplace = function(obj) {
    var retStr = this;
    for (var x in obj) {
        retStr = retStr.replace(new RegExp(x, 'g'), obj[x]);
    }
    return retStr;
};

console.log('aabbaabbcc'.allReplace({'a': 'h', 'b': 'o'}));
// console.log 'hhoohhoocc';

Почему бы не цепь, хотя? Я не вижу ничего плохого в этом.

tckmn
источник
Это круто, но мне нужно заменить подчеркивание пробелами, не пустыми, могу ли я это сделать?
Шеннон Хохкинс,
Думал так, но все же вы помогли мне понять, как выражения замены работают немного лучше :)
Шеннон Хохкинс
Ваш прототип не работает?
Можете
3
Другой вариант #|_это [#_], и вы можете также использовать +для соответствия любых матчей подряд , чтобы улучшить производительность
Ian
3
Круто, спасибо ... если нужно, замените пробелы, а другие символы str.replace(/[+ -]/g,'');просто поставьте пробел в середине.
Эквиман
53

Цепочка это круто, зачем отказываться?

В любом случае, здесь есть еще один вариант замены:

string.replace(/#|_/g,function(match) {return (match=="#")?"":" ";})

Заменить выберет "" если соответствует == "#", "" если нет.

[Обновление] Для более общего решения вы можете сохранить замещающие строки в объекте:

var replaceChars={ "#":"" , "_":" " };
string.replace(/#|_/g,function(match) {return replaceChars[match];})
Christophe
источник
4
var regex = new RegExp( Object.keys(replaceChars).join("|"), "g"); string.replace(regex,function(match) {return replaceChars[match];})Сделайте дополнительный шаг: это облегчает изменение replaceChars.
RozzA
@RozzA спасибо. Object.keys не был мейнстримом в то время.
Кристоф
Я полностью забыл о параметре функции замены для замены второго параметра, чтобы помочь мне вспомнить :)
Luckylooke
48

Если вы хотите заменить несколько символов, вы можете вызвать String.prototype.replace()аргумент замены, являющийся функцией, которая вызывается для каждого совпадения. Все, что вам нужно, это объект, представляющий сопоставление символов, которое вы будете использовать в этой функции.

Например, если вы хотите aзаменить на x, bс yи cс z, вы можете сделать что-то вроде этого:

var chars = {'a':'x','b':'y','c':'z'};
var s = '234abc567bbbbac';
s = s.replace(/[abc]/g, m => chars[m]);
console.log(s);

Выход :234xyz567yyyyxz

Войку
источник
3
так как вы используете ES6 (стрелка функции) , вы также должны заменить varс constздесь. альтернатива для расширенной поддержки браузера:var s ='234abc567bbbbac'; s = s.replace(/[abc]/g, function(m) { return {'a':'x','b':'y','c':'z'}[m]; }); console.log(s);
Феликс Гинен
1
@FelixGeenen 1. вы убиваете переносимость 2. если вы решите переопределить символы или s, вы получите ошибку времени выполнения, которая убивает ее надежность, 3. нет никаких гарантий для защиты s от мутаций и повторного связывания, кроме чисто идеологических. Замечательно видеть, что этот фрагмент будет по-прежнему работать в только что установленном windows98 при двойном щелчке / cscript / wscript:var chars = {a:'1', b:'2', c:'3'}; var s = '123abc123'; var u = s.replace(/[abc]/g, function(m) { return chars[m]; }); WScript.echo(u);
Дмитрий
это действительно хорошо Спасибо. В какой части вы использовали объект для выполнения оператора или. у вас есть документация или ссылка на то, что объясняет это. Довольно хороший вариант использования.
Кристиан Мэтью
39

Укажите /g(глобальный) флаг в регулярном выражении, чтобы заменить все совпадения вместо первого:

string.replace(/_/g, ' ').replace(/#/g, '')

Чтобы заменить одного персонажа одной вещью, а другого персонажа чем-то другим, вы не можете обойтись без двух отдельных вызовов replace. Вы можете абстрагировать его в функцию, как это сделал Doorknob, хотя я бы, вероятно, взял объект со старыми / новыми парами ключ / значение вместо плоского массива.

Марк Рид
источник
как бы я включил хэш тоже?
Шеннон Хохкинс,
4

Вы также можете попробовать это:

function replaceStr(str, find, replace) {
    for (var i = 0; i < find.length; i++) {
        str = str.replace(new RegExp(find[i], 'gi'), replace[i]);
    }
    return str;
}

var text = "#here_is_the_one#";
var find = ["#","_"];
var replace = ['',' '];
text = replaceStr(text, find, replace);
console.log(text);

findотносится к тексту, который нужно найти, и replaceк тексту, который нужно заменить на

Это заменит символы без учета регистра. Чтобы сделать иначе, просто измените флажки Regex по мере необходимости. Например: для учета регистра заменить:

new RegExp(find[i], 'g')
Тапан Бала
источник
4

Вы можете просто попробовать это:

str.replace(/[.#]/g, 'replacechar');

это заменит., - и # на ваш replacechar!

Карим Сомай
источник
Этот ответ уже был предоставлен и не обрабатывает замену других символов другими, см. OP.
Шеннон Хохкинс
3

Вот простой способ сделать это без RegEx.
Вы можете создавать прототипы и / или кэшировать вещи по своему усмотрению.

// Example: translate( 'faded', 'abcdef', '123456' ) returns '61454'
function translate( s, sFrom, sTo ){
    for ( var out = '', i = 0; i < s.length; i++ ){
        out += sTo.charAt( sFrom.indexOf( s.charAt(i) ));
    }
    return out;
}
Beejor
источник
Я знаю, что вы не заявили об этом, но не намного ли элегантнее просто использовать регулярные выражения? str.replace(/#|_/g,'')
Шеннон Хохкинс
1
@ShannonHochkins Конечно! Я не хочу ругать на RegEx; Я просто показываю другой вариант. RegEx не всегда интуитивно понятен и может быть использован «как молоток, рассматривая каждую проблему как гвоздь». Кроме того, если посмотреть на другие ответы, эта функция не является многоразовой, и ее параметры легко понять. Лично я бы взял короткий RegEx для вопроса здесь, и это имеет смысл, если вы просто ищете быстрый фрагмент кода, который вы не возражаете, не понимая полностью.
Beejor
Ну, если вам нужно перевести символы (а - ля sed у команды или а - ля Unix tr), это похоже на правильный ответ.
Эдуард
3

Пожалуйста попробуйте:

  • заменить несколько строк

    var str = "http://www.abc.xyz.com"; str = str.replace(/http:|www|.com/g, ''); //str is "//.abc.xyz"

  • заменить несколько символов

    var str = "a.b.c.d,e,f,g,h"; str = str.replace(/[.,]/g, ''); //str is "abcdefgh";

Удачи!

Чан Хунг
источник
2

Вы также можете передать объект RegExp в метод замены, например:

var regexUnderscore = new RegExp("_", "g"); //indicates global match
var regexHash = new RegExp("#", "g");

string.replace(regexHash, "").replace(regexUnderscore, " ");

Javascript RegExp

Майкл Санчес
источник
ОП не хочет связывать replaceзвонки - это не помогает избежать этого.
Деннис
2

yourstring = '#Please send_an_information_pack_to_the_following_address:';

замените "#" на "" и замените "_" пробелом

var newstring1 = yourstring.split('#').join('');
var newstring2 = newstring1.split('_').join(' ');

newstring2 - ваш результат

Хафсул Мару
источник
Ваш ответ не использует ни малейшего фрагмента jQuery, а также не следует OP, '#this #is__ #a test ### ' .split ('_'). Join ('') не будет работать как у вас
останется
@ShannonHochkins Как больше пробелов будет добавлено?
Хафсул Мару
Взгляните на мой пример, когда перед пробелом стоит подчеркивание или два подчеркивания, в результате вы получите несколько пробелов.
Шеннон Хохкинс
@ShannonHochkins спрашивающий имеет дело со строкой '#Please send_an_information_pack_to_the_following_address:'; здесь нет места почему я подумаю об этом. когда думаешь, почему только о космосе, может случиться многое другое.
Хафсул Мару
Я предлагаю вам перечитать ОП, я оригинальный постер, и вы можете ясно увидеть в моей первой переменной, var str = '#this #is__ __#a test###__';что в этой строке есть несколько пробелов.
Шеннон Хохкинс,
2

Вот еще одна версия с использованием String Prototype. Наслаждайтесь!

String.prototype.replaceAll = function(obj) {
    let finalString = '';
    let word = this;
    for (let each of word){
        for (const o in obj){
            const value = obj[o];
            if (each == o){
                each = value;
            }
        }
        finalString += each;
    }

    return finalString;
};

'abc'.replaceAll({'a':'x', 'b':'y'}); //"xyc"
Диего Фортес
источник
1

Я не знаю, насколько это поможет, но я хотел удалить <b>и </b>из моей строки

поэтому я использовал

mystring.replace('<b>',' ').replace('</b>','');

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

Кришикеш Кале
источник
-1

Вот функция «безопасного HTML», использующая функцию многократной замены «уменьшить» (эта функция применяет каждую замену ко всей строке, поэтому зависимости между заменами значительны).

// Test:
document.write(SafeHTML('<div>\n\
    x</div>'));

function SafeHTML(str)
    {
    const replacements = [
        {'&':'&amp;'},
        {'<':'&lt;'},
        {'>':'&gt;'},
        {'"':'&quot;'},
        {"'":'&apos;'},
        {'`':'&grave;'},
        {'\n':'<br>'},
        {' ':'&nbsp;'}
        ];
    return replaceManyStr(replacements,str);
    } // HTMLToSafeHTML

function replaceManyStr(replacements,str)
    {
    return replacements.reduce((accum,t) => accum.replace(new RegExp(Object.keys(t)[0],'g'),t[Object.keys(t)[0]]),str);
    }
Дэвид Спектор
источник
Спасибо за этот пост, однако он довольно обширный по сравнению с принятым ответом
Шеннон Хохкинс
Ответ на вопрос - однострочная функция. Как это "обширно"? Безопасный ввод данных пользователем является важным примером. Вы слишком критичны. «уменьшить» - очень полезная техника, о которой вы должны знать.
Дэвид Спектор
Я сказал, что ваш ответ слишком обширный, он намного больше кода, вы все равно используете регулярные выражения, просто делаете процесс слишком запутанным, не зная, как вы думаете, ваш ответ является сокращением по сравнению с любым из этих ответов ...
Шеннон Хохкинс
Мой ответ - ответ «уменьшить», потому что он использует функцию Array.prototype.reduce. Более короткий ответ может использовать строку вместо ключей свойства, используя тот факт, что функция «безопасного HTML» работает только при замене отдельных символов. Я призываю вас придумать более элегантный ответ вместо грубых жалоб на публику.
Дэвид Спектор
На самом деле я сказал «спасибо», и дал вам критику, вы взяли это и решили написать что-то странное, если мы собираемся начать с функциональных методов для выполнения, а не с прототипных методов, как мы должны быть, тогда что-то гораздо проще, например: jsfiddle .net / shannonhochkins / xsm9j610 / 21
Шеннон Хохкинс,