LoginSignup
15
17

More than 5 years have passed since last update.

1回のreplaceで複数のパターンを置き換える例2つ

Posted at

Stringのreplace()関数は第2引数に関数を指定することも出来ます。
String.prototype.replace() - JavaScript | MDN

それを使って1回のreplaceで複数のパターンを置き換える例を2つ上げます。MITライセンスとします。

escapeHTML

1つめはHTMLをエスケープする関数です。Underscore.jsを使っている場合はescapeが用意されていますのでそちらを使いましょう。これはUnderscore.jsが無いときに使うためのスタンドアロン版です。

var escapeHTML = function() {
  var escapes = {
        '&': '&',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#x27;'
      },
      re = /[&<>"']/g;
  function replacer(c) { return escapes[c]; }
  return function(html) { return html.replace(re, replacer); };
}();

関数を定義する時点で評価しておける部分はなるべく評価するようにして、実際に呼び出されるときの処理を少なくなるようにしています。
具体的にはreとreplacerはescapeHTMLの実行時に毎回計算されるわけではなくて、上のコードを実行した時点で1度だけ計算されます。

使い方の例は以下の通りです。

console.log(escapeHTML('<a href=\'/foo?a=1&amp;b=2\' class="foo">here</a>'));

出力

&lt;a href=&#x27;/foo?a=1&amp;amp;b=2&#x27; class=&quot;foo&quot;&gt;here&lt;/a&gt;

tr

Unixにはtrというコマンドがあります。tr(1): translate/delete char - Linux man page
2つめの例はこれと似たような置換を実現する関数です。

function buildTr(from, to) {
  var replaces = {}, i, c, exp = '', re;
  for (i in from) {
    c = from[i];
    replaces[c] = to.substr(i, 1);
    exp += '[]-^\\'.indexOf(c) < 0 ? c : '\\' + c;
  }
  re = RegExp('[' + exp + ']', 'g');
  function replacer(c) { return replaces[c]; }
  return function(str) { return str.replace(re, replacer); };
}

こちらも基本方針は1つめの例と同様です。置換元の文字列が引数で渡されるので、動的に正規表現を作っています。正規表現のキャラクタセット(Regular Expressions - JavaScript | MDN)を使っているので、その中で意味を持つメタキャラクタ[]-^\はバックスラッシュでエスケープしています。

変換元は配列の添字でfrom[i]のように文字を取り出しているのに対して、変換先はto.substr(i, 1)のようにしているのは、toの文字数が少ない場合は空文字に置換したいからです。to[i]でiがtoの長さ以上だとundefinedになりますが、to.substr(i, 1)なら空文字になるので後者を使っています。

使い方の例です。第1引数より第2引数は1文字短いので、第1引数の最後の文字xは削除されます。他の文字は対応する文字に置き換えられます。

var tr = buildTr(
  'あいうえおやゆよわつは。[]-\\^x',
  'ぁぃぅぇぉゃゅょゎっゎo{}_/~'
);
console.log(
  tr('replaceの第二引数に関数を使うことでreplaceを一回で済ませています。変換元は配列の添字でfrom[i]のように文字を取り出しているのに対して、変換先はto.substr(i, 1)のようにしているのは、toの文字数が少ない場合は空文字に置換したいからです。あとはメタ文字のテスト-\\^と消すテストx。わあい、えいゆう、おやつ'));

出力例です。

replaceの第二引数に関数を使ぅことでreplaceを一回で済ませてぃますo変換元ゎ配列の添字でfrom{i}のょぅに文字を取り出してぃるのに対して、変換先ゎto.substr(i, 1)のょぅにしてぃるのゎ、toの文字数が少なぃ場合ゎ空文字に置換したぃからですoぁとゎメタ文字のテスト_/~と消すテストoゎぁぃ、ぇぃゅぅ、ぉゃっ
15
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17