かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript 該当する文字を全部変換したいメモ

例えば次のようなテキストを

"藤堂ユリカ\n一ノ瀬かえで\n神崎美月"

👇

"藤堂ユリカ 一ノ瀬かえで 神崎美月"

のように置き換えたい時

JavaScriptにはreplaceAllのようなメソッドがないので、

const str = "藤堂ユリカ\n一ノ瀬かえで\n神崎美月";
str.replace("\n", " ");
// => "藤堂ユリカ 一ノ瀬かえで\n神崎美月"

単純にstr.replace()を使っても最初にマッチした文字しか置き換えられません。

str.replace() で正規表現を使って置き換える

正攻法。
str.replace() の検索文字を正規表現( RegExp )にする方法。
g(グローバルサーチ)オプションを使うことで全てのマッチを置き換えることができます。

const str = "藤堂ユリカ\n一ノ瀬かえで\n神崎美月";
str.replace(/\n/g, ' ');
// => "藤堂ユリカ 一ノ瀬かえで 神崎美月"

str.split().join() で置き換える

split()メソッドが指定した区切り文字全てで分割して配列をかえすことを利用して、str.split('検索文字').join('変換文字')としてしまえば一括変換に利用できます。

const str = "藤堂ユリカ\n一ノ瀬かえで\n神崎美月";
str.split("\n").join(' ');
// => "藤堂ユリカ 一ノ瀬かえで 神崎美月"

splitで配列になっているので、reduce()で値を弄ったりして合算することも出来ます。

const str = "藤堂ユリカ\n一ノ瀬かえで\n神崎美月";
str.split("\n").reduce((sum, val)=> {
  if( /^神崎美月$/.test(val) ) {
    val = 'レジェンド美月';
  }
  return `${val}🌟${sum}`;
});
// => "レジェンド美月🌟一ノ瀬かえで🌟藤堂ユリカ"

 

単一な文字を一括して変換したい時、str.split('検索文字').join('変換文字')はハック的だけど簡潔で良いなと思いました。
処理的には正攻法な正規表現の方が関数呼び出しも1つだし高速な気もしますが…

おまけ str.replace() の第二引数(置換える文字)は関数にできる

str.replace()のドキュメントを見ていて、第二引数に関数が取れる事を知ったので試してみました。

str.replace(regexp|substr, newSubstr|function)
function (replacement)
新しい部分文字列を生成するために実行される関数で、regexpsubstr でマッチしたものを置き換えるのに使われます。この関数に渡される引数は下記の "Specifying a function as a parameter" で述べられています。

const str = "藤堂ユリカ\n一ノ瀬かえで\n神崎美月";
str.replace(/(.+)\n/g, (...val)=> {
    console.log(val);
    return 'ジョニー別府 ';
});
// => [ '藤堂ユリカ\n', '藤堂ユリカ', 0, '藤堂ユリカ\n一ノ瀬かえで\n神崎美月' ]
// => [ '一ノ瀬かえで\n', '一ノ瀬かえで', 6, '藤堂ユリカ\n一ノ瀬かえで\n神崎美月' ]
// res => "ジョニー別府 ジョニー別府 神崎美月"

第二引数を関数にした場合の引数は、

  • match: マッチした文字列
  • p1, p2, ...: 正規表現の場合、キャプチャされたサブマッチ文字列
  • offset: マッチした箇所のオフセット
  • strings: 元の文字列

として渡され、return した値に第一引数のマッチした部分が置き換えられるようです。

cf. 引数としての関数の指定セクション
正規表現で一括変換マッチさせて、サブマッチ文字列をjoinさせるサンプルが書かれてて興味深かったです。


[参考]

スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)

スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)