Substitua vários caracteres em uma chamada de substituição


257

Pequena pergunta muito simples, mas não entendo bem como fazê-lo.

Preciso substituir todas as instâncias de '_' por um espaço e todas as instâncias de '#' por nada / vazio.

var string = '#Please send_an_information_pack_to_the_following_address:';

Eu tentei isso:

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

Eu realmente não gosto de encadear comandos como este. Existe outra maneira de fazer isso em um?


Veja a resposta a esta pergunta: stackoverflow.com/questions/7072330/…
— DeweyOx

Respostas:


515

Use o operador OR ( |):

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

Você também pode usar uma classe de personagem:

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

Violino

Se você deseja substituir o hash por uma coisa e o sublinhado por outra, será necessário encadear. No entanto, você pode adicionar um protótipo:

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';

Por que não cadeia, no entanto? Não vejo nada de errado nisso.


Isso é legal, mas preciso substituir sublinhados por espaços não vazios, posso fazer isso?
— Shannon Hochkins

Pensava assim, mas ainda assim você me ajudou a entender como substituir expressões trabalhar um pouco melhor :)
— Shannon Hochkins

Seu protótipo não funciona? você é capaz de fornecer um exemplo no violino, eu continuo recebendo erros
— Shannon Hochkins

3
Outra opção para #|_é [#_], e assim como você pode usar +para coincidir com quaisquer jogos consecutivos para melhorar o desempenho
— Ian

3
Legal obrigado ... se necessário, substitua espaços em branco e outros símbolos str.replace(/[+ -]/g,'');apenas coloque espaço em branco no meio.
— Equiman 5/05

53

Encadeamento é legal, por que descartá-lo?

Enfim, aqui está outra opção em uma substituição:

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

A substituição escolherá "" se corresponder == "#", "" se não.

[Atualização] Para uma solução mais genérica, você pode armazenar suas seqüências de substituição em um objeto:

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

4
dê o passo extra: var regex = new RegExp( Object.keys(replaceChars).join("|"), "g"); string.replace(regex,function(match) {return replaceChars[match];})isso facilita a modificação dos replaceChars.
— RozzA 04/08/19

@RozzA thanks. Object.keys não era mainstream no momento.
— Christophe

Eu esqueci completamente opção função de substituição de cerca de substituir segundo parâmetro, por me ajudar a lembrar :)
— Luckylooke

48

Se você deseja substituir vários caracteres, pode chamar o String.prototype.replace()argumento de substituição, sendo uma função que é chamada para cada correspondência. Tudo o que você precisa é de um objeto que represente o mapeamento de caracteres que você usará nessa função.

Por exemplo, se você quiser asubstituir por x, bpor ye ccom z, poderá fazer algo assim:

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

Saída :234xyz567yyyyxz


3
desde que você use o ES6 (função de seta), você também deve substituir varpor constaqui. uma alternativa para suporte estendido ao navegador:var s ='234abc567bbbbac'; s = s.replace(/[abc]/g, function(m) { return {'a':'x','b':'y','c':'z'}[m]; }); console.log(s);
— Felix Geenen 23/03

1
@FelixGeenen 1. você mata a portabilidade 2. se optar por redefinir caracteres ou s, você receberá um erro de tempo de execução, o que acaba com sua 'robustez', 3. não há garantia de proteger s contra mutações e religiões que não sejam puramente ideológicas. É uma coisa maravilhosa ver que esse trecho ainda funcionará no windows98 recém-instalado no clique duplo / 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);
— Dmitry

isto é muito bom. obrigado. Qual é a parte em que você usou um objeto para fazer uma declaração ou. você tem documentação ou referência a algo que explica isso? Muito bom caso de uso.
— Christian Matthew

39

Especifique o /gsinalizador (global) na expressão regular para substituir todas as correspondências em vez da primeira:

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

Para substituir um caractere por uma coisa e um caractere diferente por outra, você não pode realmente precisar de duas chamadas separadas replace. Você pode abstraí-lo para uma função como a Maçaneta da porta, embora eu provavelmente desejaria que ele pegasse um objeto antigo / novo como pares chave / valor em vez de uma matriz plana.


como incluiria o hash também?
— Shannon Hochkins

4

Você também pode tentar o seguinte:

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);

findrefere-se ao texto a ser encontrado e replaceao texto a ser substituído por

Isso substituirá caracteres que não diferenciam maiúsculas de minúsculas. Para fazer o contrário, altere os sinalizadores Regex conforme necessário. Por exemplo: para caso sensível, substitua:

new RegExp(find[i], 'g')

4

Você pode apenas tentar o seguinte:

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

isso substituirá., - e # pelo seu substitechar!


Esta resposta já foi fornecida e não lida com a substituição de caracteres diferentes por outros, consulte OP.
— Shannon Hochkins

3

Aqui está uma maneira simples de fazer isso sem o RegEx.
Você pode criar protótipos e / ou armazenar em cache as coisas conforme desejado.

// 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;
}

Eu sei que você não indicou, mas não é muito mais elegante usar apenas regex? str.replace(/#|_/g,'')
— Shannon Hochkins

1
@ ShannonHochkins Com certeza! Não pretendo me basear no RegEx; Estou apenas mostrando outra opção. O RegEx nem sempre é intuitivo e se presta a ser usado "como um martelo, tratando todos os problemas como um prego". Além disso, olhando para as outras respostas, como uma função reutilizável, essa não é muito mais longa e os parâmetros são fáceis de entender. Pessoalmente, eu faria um pequeno RegEx para a pergunta aqui, e faz sentido se você está apenas procurando um trecho rápido de apresentação que você não se importa de não entender completamente.
— Beejor

Bem, se você precisar traduzir um caractere (à la sed y command ou à Unix tr), esta parece ser a resposta certa.
— Édouard

3

Tente por favor:

  • substituir várias cordas

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

  • substituir vários caracteres

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

Boa sorte!


2

Você também pode passar um objeto RegExp para o método de substituição, como

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

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

Javascript RegExp


O OP não deseja encadear replacechamadas - isso não ajuda a evitar isso.
— Dennis

2

yourstring = '#Envie send_an_information_pack_to_the_following_address:';

substitua '#' por '' e substitua '_' por um espaço

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

newstring2 é o seu resultado


Sua resposta não usa um fragmento de jQuery e também não segue o OP, '#this #is__ #a test ### ' .split ('_'). Join ('') não funcionaria como você iria acabar com mais espaços em branco
— Shannon Hochkins

@ ShannonHochkins Como mais espaços em branco serão adicionados?
— Hafsul Maru

Dê uma olhada no meu exemplo, quando houver um sublinhado antes de um espaço, ou dois sublinhados, você terá vários espaços.
— Shannon Hochkins

@ShannonHochkins, o interlocutor lida com a sequência '#Por favor, envie uma informação_pacote_para_a_fazer o seguinte endereço:'; não há espaço aqui. Por que eu vou pensar nisso. quando pensar, por que apenas sobre o espaço, muitas outras coisas podem acontecer.
— Hafsul Maru 23/01

Eu sugiro que você leia o OP, eu sou o pôster original e você pode ver claramente na minha primeira variável var str = '#this #is__ __#a test###__';que há claramente vários espaços nessa string.
— Shannon Hochkins

2

Aqui está outra versão usando o String Prototype. Aproveitar!

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

Não sei se isso ajudará, mas eu queria remover <b>e</b> da minha string

então eu usei

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

Então, basicamente, se você deseja que um número limitado de caracteres seja reduzido e não perca tempo, isso será útil.


-1

Aqui está uma função "HTML seguro" usando uma função de substituição múltipla 'reduzir' (essa função aplica cada substituição a toda a cadeia de caracteres, portanto, as dependências entre substituições são significativas).

// 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);
    }

Graças ao cargo, no entanto, é bastante extensa em comparação com a resposta aceita
— Shannon Hochkins

A resposta para a pergunta é uma função de uma linha. Como isso é "extenso"? Tornar a entrada do usuário segura é um exemplo importante. Você é muito crítico. 'reduzir' é uma técnica muito útil que você deve conhecer.
— David Spector

Eu disse que sua resposta é muito extensa, é muito mais código, você está usando expressões regulares de qualquer maneira, apenas tornando o processo muito complicado, sem saber como você acha que sua resposta é uma redução em comparação com qualquer uma dessas respostas ...
— Shannon Hochkins 9/09/19

Minha resposta é uma resposta 'reduzida' porque ela usa a função Array.prototype.reduce. Uma resposta mais curta pode usar uma sequência em vez de chaves de propriedade, explorando o fato de que uma função "HTML seguro" funciona apenas na substituição de caracteres únicos. Eu desafio você a encontrar uma resposta mais elegante em vez de reclamar rudemente em público como este.
— David Spector

Na verdade, eu agradeci, e fiz críticas, você aceitou e decidiu escrever algo sarcástico, se vamos começar com métodos funcionais para executar, em vez de métodos encadeados prototípicos como deveríamos ser, algo muito mais simples como: jsfiddle .net / shannonhochkins / xsm9j610 / 21
— Shannon Hochkins
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.