tr
Perlの関数と同様に、文字列内の文字セットを別のセットにマップする方法を見つけようとしています。
JS と Perl で同等の関数を示しているこのサイトを見つけましたが、残念ながら同等の tr はありません。
Perlのtr
(音訳) 関数は、文字を 1 対 1 でマップします。
data =~ tr|\-_|+/|;
マップします
- => + and _ => /
これを JavaScript で効率的に行うにはどうすればよいでしょうか?
tr
Perlの関数と同様に、文字列内の文字セットを別のセットにマップする方法を見つけようとしています。
JS と Perl で同等の関数を示しているこのサイトを見つけましたが、残念ながら同等の tr はありません。
Perlのtr
(音訳) 関数は、文字を 1 対 1 でマップします。
data =~ tr|\-_|+/|;
マップします
- => + and _ => /
これを JavaScript で効率的に行うにはどうすればよいでしょうか?
組み込みの同等物はありませんが、次の方法でそれに近づけることができますreplace
。
data = data.replace(/[\-_]/g, function (m) {
return {
'-': '+',
'_': '/'
}[m];
});
「効率的」を保証することはできませんが、これは正規表現とコールバックを使用して置換文字を提供します。
function tr( text, search, replace ) {
// Make the search string a regex.
var regex = RegExp( '[' + search + ']', 'g' );
var t = text.replace( regex,
function( chr ) {
// Get the position of the found character in the search string.
var ind = search.indexOf( chr );
// Get the corresponding character from the replace string.
var r = replace.charAt( ind );
return r;
} );
return t;
}
検索文字と置換文字の長い文字列の場合、それらをハッシュに入れて、関数がそこから返されるようにすることをお勧めします。つまり、tr/abcd/QRST/ はハッシュ { a: Q, b: R, c: S, d: T } になり、コールバックは hash[ chr ] を返します。
方法:
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];
});
};
完璧な例:
var s = "I think Peak rocks!"
s.mapReplace({"I think":"Actually","rocks":"sucks"})
// console: "Actually Peak sucks!"
この関数は、Perl での構築方法に似ています。
function s(a, b){ $_ = $_.replace(a, b); }
function tr(a, b){ [...a].map((c, i) => s(new RegExp(c, "g"), b[i])); }
$_ = "Εμπεδοκλης ο Ακραγαντινος";
tr("ΑΒΓΔΕΖΗΘΙΚΛΜΝΟΠΡΣΤΥΦΧΩ", "ABGDEZITIKLMNOPRSTIFHO");
tr("αβγδεζηθικλμνοπρστυφχω", "abgdezitiklmnoprstifho");
s(/Ξ/g, "X"); s(/Ψ/g, "Ps");
s(/ξ/g, "x"); s(/ψ/g, "Ps");
s(/ς/g, "s");
console.log($_);
Perlでは、次のように書くこともできます
tr{-_}{+/}
なので
my %trans = (
'-' => '+',
'_' => '/',
);
my $class = join '', map quotemeta, keys(%trans);
my $re = qr/[$class]/;
s/($re)/$trans{$1}/g;
この後者のバージョンは、JSで問題なく実装できます。
(私のバージョンには、Jonathan Lonowskiのソリューションの複製がありません。)
a
これにより、すべての sb
とすべての がマップさy
れます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];
編集:
どうやら文字列でそれを行うことはできません。代替案は次のとおりです。
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('');
Jonathan Lonowskiの回答に似ていますが、単一のtr文字だけでなく、単語のサポートがあります
"aaabbccddeeDDDffd".replace( /(a|cc|DDD|dd)/g, m => ({'a':'B', 'cc':'DDD', 'DDD':'ZZZ', dd:'QQ'}[m]) )
// RESULT: "BBBbbDDDQQeeZZZffd"