18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptのString#replaceは思っていたより高機能だった

Posted at

TL; DR

Stringオブジェクトのreplaceメソッドは、第2引数に関数をとれて便利。

はじめに

JavaScriptで文字列置換したいときに、replaceメソッドをよく使います。例えば、スペースをハイフンにしたければこんな具合です。

"foo bar".replace(" ", "-") // => "foo-bar"

ただ、これだと最初にマッチしたスペースしか置換されません。

"foo bar baz".replace(" ", "-") // => "foo-bar baz"

第1引数には正規表現も書けるので、gオプションをつけた正規表現を使えばすべてのスペースが置換できます。

"foo bar baz".replace(/ /g, "-") // => "foo-bar-baz"

できました。ここまでは単純な置換です。

置換パターン

さて、もっと込み入ったことをしたいとします。例えば、各単語をかっこで囲みたいとしましょう。"foo bar baz"を、"(foo) (bar) (baz)"にします。このようなマッチした文字列を使い回す置換は、置換パターンが便利です。

"foo bar baz".replace(/\w+/g, "($&)") // => "(foo) (bar) (baz)"

ここでは、マッチした文字列を表す$&という置換パターンを使いました。

キャプチャした文字列を$1, $2... で参照することもできます。

"John,male\nJane,female".replace(/(\w+),(\w+)/g, "name: $1, gender: $2") // name: john, gender: male\nname: jane, gender: female

話はこれで終わりません。更に高度なことができます。

第2引数の関数指定

replaceの第2引数には関数が指定できます。第1引数がマッチするたびに呼ばれます。引数には、マッチした文字列に関する情報が入ります。

"foo bar baz".replace(/\w+/g, match => match.toUpperCase()) // => "FOO BAR BAZ"

これでもう何でもありですね。ちょっとした自作テンプレートのようなこともできます。

const bindings = {
  host: 'example.com',
  port: 8080
}
// キャプチャした文字列は2つ目の引数に入ります。
// 2つ以上キャプチャした場合は3つ目、4つ目…の引数に入ります。
"http://{{host}}:{{port}}".replace(/{{(\w+)}}/g, (_, key) => bindings[key]) // => "http://example.com:8080"

便利。

参考文献

String.prototype.replace() - JavaScript | MDN

18
11
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
18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?