2012-05-23 12 views
29

Ho cercato di capire come mappare un set di caratteri in una stringa su un altro set simile alla funzione tr in Perl.Come si sostituiscono i caratteri in Javascript in modo simile alla funzione 'tr' in Perl?

Ho trovato this site that shows equivalent functions in JS and Perl, ma purtroppo non equivalente.

la funzione tr (traslitterazione) in Perl mappe caratteri 1-1, quindi

 data =~ tr|\-_|+/|; 

sarebbe mappare

 - => + and _ =>/

Come può essere fatto in modo efficiente in JavaScript?

risposta

39

Non v'è un built-in equivalente, ma è possibile avvicinarsi ad uno con replace:

data = data.replace(/[\-_]/g, function (m) { 
    return { 
     '-': '+', 
     '_': '/' 
    }[m]; 
}); 
+1

molto bello con la funzione di callback, cosa restituisce {..} [m]? – qodeninja

+2

@qodeninja L'oggetto ('{...}') definisce la mappatura dei caratteri, con le corrispondenze previste come chiavi/proprietà e sostituzioni come valori. La corrispondenza corrente, 'm', viene quindi utilizzata per cercare la propria sostituzione (' [m] ') dall'oggetto, che viene restituito a' replace' per eseguire la sostituzione effettiva. –

+0

Apparentemente la risposta è "sì", ma non in modo succinto come Perl. –

3

Ciò mappare tutti a s per b e tutto y a z

var map = { a: 'b', y: 'z' }; 
var str = 'ayayay'; 

for (var i = 0; i < str.length; i++) 
    str[i] = map[str[i]] || str[i]; 

EDIT:

A quanto pare non è possibile farlo con le stringhe. Ecco un'alternativa:

var map = { a: 'b', y: 'z' }; 
var str = 'ayayay', str2 = []; 

for (var i = 0; i < str.length; i++) 
    str2.push(map[str[i]] || str[i]); 
str2.join(''); 
+0

Perché inserire una domanda senza prove e perché lasciare la risposta non funzionante in atto dopo la modifica? –

1

In Perl, si può anche scrivere

tr{-_}{+/} 

come

my %trans = (
    '-' => '+', 
    '_' => '/', 
); 

my $class = join '', map quotemeta, keys(%trans); 
my $re = qr/[$class]/; 

s/($re)/$trans{$1}/g; 

Quest'ultima versione può sicuramente essere implementata in JS senza molti problemi.

(La mia versione manca la duplicazione della soluzione di Jonathan Lonowski.)

5

Non posso garantire per 'efficiente', ma questo utilizza una regex e una funzione di callback per fornire il carattere di sostituzione.

Per stringhe lunghe di caratteri di ricerca e sostituzione, potrebbe valere la pena di inserirli in un hash e restituire la funzione. cioè, tr/abcd/QRST/diventa l'hash {a: Q, b: R, c: S, d: T} e il callback restituisce hash [chr].

+1

+1, anche se: Non supporta "]", "\" e "^". Non supporta gli intervalli. Non supporta gli escape "\". – ikegami

4

Metodo:

String.prototype.mapReplace = function(map) { 
    var regex = []; 
    for(var key in map) 
     regex.push(key.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")); 
    return this.replace(new RegExp(regex.join('|'),"g"),function(word){ 
     return map[word]; 
    }); 
}; 

Un esempio perfetto:

var s = "I think Peak rocks!" 
s.mapReplace({"I think":"Actually","rocks":"sucks"}) 
// console: "Actually Peak sucks!" 
+0

qual è il rendimento rispetto alla risposta? – qodeninja

+1

@qodeninja È la stessa tecnica, mentre questo metodo consente di utilizzare una mappatura dinamica KV JSON. Potrebbe essere più lento della risposta, perché genera il Regex e il dizionario di sostituzione per te. Quindi usa questo metodo mentre hai bisogno di una sostituzione dinamica, usa la risposta se hai solo bisogno di gestire il set di parole statiche. – PeakJi

Problemi correlati