JavaScriptで複数置換をスマートにやりたい
JavaScriptで複数パターンの置換をまとめてやりたいと思っていたとき、なかなかしっくりくる方法がありませんでした。自分でいろいろ試してみた結果、お気に入りの方法を見つけたのでご紹介します。
やりたかったこと
文字列を操作するとき、複数の文字列をまとめて置換したい…というシチュエーションがあると思います。例えば、
・#\/
という文字列で、記号を置換によりエンコードしたいというとき。
この場合、replaceメソッドを用いた通常の方法だと以下のようになります。
let str = '・#\/';
str = str.replace(/・/g, '%E3%83%BB').replace(/#/g, '%23').replace(/\//g, '%2F').replace(/\\/g, '%5C');
※gは対象パターンの全置換のためのオプションフラグ。
なんだかreplaceがたくさんひっついていますね。これはメソッドチェーンといって、繰り返しreplaceを適用することによって複数置換する…という方法です。
ですが、求めていたのはこれじゃない。置換パターンが2, 3個ならまだ良いですが、ある程度多くのパターンをまとめて置換したいという場合、replaceを繋げまくるのは大変です。しかも見た目もよろしくない。
ということで、別の方法を考えてみました。
スマートに複数置換
配列とループを利用して、複数パターンの置換を実現します。以下のような形です。
let str = "・#\/"
const keys = [/・/g, /#/g, /\//g, /\\/g];
const reps = ["%E3%83%BB", "%23", "%2F", "%5C"];
for (let i = 0; i < keys.length; i++) {
str = str.replace(keys[i], reps[i]);
}
変換対象文字列をkeys
、置換文字列をreps
として、それぞれ配列に格納しておきます。そしてkeys
の長さ分forループを回し、対応する位置の文字列を置き換えていきます。
ループが回るたびにstr
が上書きされ、結果として複数パターンの置換が実現できるというわけです。メソッドチェーンを疑似的に適用した形になっています。
通常のメソッドチェーンと比べて少し行数は増えてしまいますが、置換パターンを配列で一元管理できるので扱いやすく、個人的には気に入っています。
注意点:置換の順番に注意
通常の方法と今回の方法どちらにもいえることですが、置換をする際には順番に注意が必要です。
例えば、先ほどの文字列で「・」が実体参照コード「・」として表示されていた場合、「#」の置換を先にすると思い通りの結果が得られません。
let str = '・#\/';
str = str.replace(/#/g, '%23').replace(/・/g, '%E3%83%BB').replace(/\//g, '%2F').replace(/\\/g, '%5C');
上の例では「#」の置換が先に適用されてしまい、うまく「・」部分を変換できなくなります。期待通りの動作にするには、置換を入れ替える必要があります。
コメントを書き込む