JavaScript:文字列を置換するreplace()を極める

TwitterFacebookHatena

TL;DR

この記事では、replace() メソッドの実装方法について詳しく解説しますね。一言でいうと replace() メソッドとは、文字列や配列内の特定の値を別の値に置き換えるためのものです。

開発環境 バージョン
Next.js 13.4.4
TypeScript 5.0.4
Emotion 11.11.0
React 18.2.0

replace() メソッドとは?

replace() メソッドは、文字列内で特定のパターンまたは値を見つけて新しい値に置き換える際に使用される JavaScript のメソッドです。特定のパターンは、文字列または正規表現で指定できます。また、新しい値は、文字列または関数で指定できます。この方法は、非常に強力で、さまざまな文字列操作に活用できます。

最初にマッチしたもののみを置換する

基本的な使用例を見てみましょう。

const str = 'こんにちは、世界'
const newStr = str.replace('世界', 'みなさん')
console.log(newStr) // "こんにちは、みなさん"

この例では、'世界'という文字列を'みなさん'に置き換えています。

複数の文字列を置換する

複数の文字列を置換するためには、replace() メソッドをチェインすることで実現できます。以下に、その例を示します。

let str = '今日は晴れです。でも、明日は雨です。'

str = str.replace('晴れ', '雨').replace('明日', '今日')

console.log(str) // "今日は雨です。でも、今日は雨です。"

この例では、元の文字列 '今日は晴れです。でも、明日は雨です。' の '晴れ' を '雨' に、そして '明日' を '今日' に置換しています。結果として出力される文字列は '今日は雨です。でも、今日は雨です。' となります。

ただし、この方法では最初にマッチした文字列のみが置換されます。したがって、もし同じ文字列が複数回出現し、それら全てを置換したい場合は正規表現を用いると良いでしょう。以下にその例を示します。

let str = '今日は晴れです。でも、明日は晴れです。'

str = str.replace(/晴れ/g, '雨').replace(/明日/g, '今日')

console.log(str) // "今日は雨です。でも、今日は雨です。"

この例では、正規表現 '/晴れ/g' と '/明日/g' を使用しています。'/g' は正規表現のグローバル検索フラグで、これを使用することで文字列中の全ての '晴れ' と '明日' が置換対象となります。

正規表現で置換する

正規表現により、文字列内の特定のパターンを探して置換するということが可能になります。

以下に簡単な例を示します。

const str = '私は犬が好きです。でも、犬は私が好きですか?'
const newStr = str.replace(//g, '猫')

console.log(newStr) // "私は猫が好きです。でも、猫は私が好きですか?"

このコードでは、/犬/g が正規表現です。/犬/g は文字列中の全ての "犬" を指定します。ここで、g は "global" の略で、全体の文字列を対象に置換を行うことを意味します。

したがって、このコードは文字列中の全ての "犬" を "猫" に置換します。

また、正規表現では大文字小文字を無視する i フラグも利用できます。例えば、/犬/gi とすると、大文字の "犬" も小文字の "犬" も全て "猫" に置換します。

このように、正規表現を用いると非常に柔軟な置換が可能となります。

全ての部分文字列を置換する

replaceAll() というメソッドも存在します。このメソッドは、指定した全ての部分文字列を置換するという機能を提供しています。

replace() メソッドが最初にマッチしたもののみを置換するのに対し、replaceAll() メソッドは指定した部分文字列全てを置換します。そのため、正規表現を使わなくても全ての部分文字列を置換することができます。

以下に、replaceAll() メソッドを使用した例を示します:

let str = '今日は晴れです。でも、明日は晴れです。'

str = str.replaceAll('晴れ', '雨').replaceAll('明日', '今日')

console.log(str) // "今日は雨です。でも、今日は雨です。"

この例では、文字列中の全ての '晴れ' と '明日' がそれぞれ '雨' と '今日' に置換されています。

ただし、replaceAll() メソッドは比較的新しいメソッドであり、全ての環境でサポートされているわけではない点に注意が必要です。サポートされていない環境では代わりに正規表現と replace() メソッドを用いることで同様の結果を得ることができます。

第二引数として特殊な置換パターンを使用する

文字列の置換を行う際に、replace() メソッドの第二引数として特殊な置換パターンを用いることができます。これらのパターンは、特定の意味を持つ文字列に置き換えられます。

以下に、それらの置換パターンを一覧表としてまとめます。

パターン 説明
$$ 「$」という文字を挿入します。
$& マッチした部分全体を挿入します。
`$`` マッチした部分より前の部分を挿入します。
$' マッチした部分より後の部分を挿入します。
$n n 番目のキャプチャグループ(n は 1 から 9 までの整数)を挿入します。
$<name> name という名前のキャプチャグループを挿入します。名前付きキャプチャグループの特性。

それぞれのパターンの使用例を以下に示します。

const str = 'こんにちは、世界'
let newStr = str.replace('世界', '$$')
console.log(newStr) // "こんにちは、$"

newStr = str.replace('世界', '$&')
console.log(newStr) // "こんにちは、世界"

newStr = 'こんにちは、世界、こんにちは'.replace(/(こんにちは)(世界)\1/, '$1')
console.log(newStr) // "こんにちは、こんにちは"

注意:置換パターンは、文字列置換の第二引数として使用されます。関数を置換として使用する場合、これらのパターンは適用されません。関数を使用した置換では、関数自体が置換の結果を決定します。

第二引数として関数を指定する

replace() メソッドの第二引数として関数を指定する場合、その関数は以下の引数を受け取ることができます。これらの引数は、関数が呼び出される際に自動的に渡されます。

以下に、それらの引数を一覧表としてまとめます。

引数名 値の説明
match マッチした部分全体の文字列です。
p1, p2, … 括弧によりキャプチャされた各部分の文字列です。(キャプチャグループが存在する場合)
offset マッチした部分が元の文字列で始まる位置(インデックス)です。
string replace() メソッドが呼び出された元の文字列です。
groups 名前付きキャプチャグループのオブジェクトです。(存在する場合)

それぞれの引数の使用例を以下に示します。

const str = 'こんにちは、世界'

const newStr = str.replace(/(世界)/, (match, p1, offset, string) => {
  console.log(`Match: ${match}`)
  console.log(`Capture Group 1: ${p1}`)
  console.log(`Offset: ${offset}`)
  console.log(`Original String: ${string}`)

  return 'Universe'
})

console.log(newStr) // "こんにちは、Universe"

このコードスニペットでは、replace() メソッドに関数を指定し、その関数内でマッチした部分、キャプチャグループ 1、マッチの位置、そして元の文字列をログ出力しています。そして、関数は 'Universe' を返しており、これにより元の文字列中の '世界' が 'Universe' に置換されます。

Next.js で、replace() メソッドを実装

Next.js と TypeScript で replace() メソッドを使った簡単な例を見ていきましょう。

components/Greeting.tsx

import React from 'react'

type Props = {
  greeting: string
}

const Greeting = ({ greeting }: Props) => {
  const replaceWorld = () => {
    return greeting.replace('世界', 'Next.jsユーザー')
  }

  return <h1>{replaceWorld()}</h1>
}

export default Greeting

pages/index.tsx

import Greeting from '../components/Greeting'

const Home = () => {
  return <Greeting greeting="こんにちは、世界" />
}

export default Home

Greeting.tsx コンポーネントでは、greeting というプロパティを受け取り、その中の '世界' を 'Next.js ユーザー' に置き換えています。この置

き換えられた挨拶は、最終的に <h1> タグ内で表示されます。

API データを取得して、一部の単語を置換する

さらに一歩進んで API の値を変更します。microCMS からデータを取得した後に、特定の単語を置換してみましょう。

この場合、Next.js のサーバーサイドレンダリング(SSR)やサーバーレス関数(API Routes)を使って microCMS からデータを取得します。そして、その取得したデータの中の特定の文字列を置換します。

ここでは、Next.js の API Routes を使って microCMS からデータを取得し、取得したデータの中から特定の単語を別の単語に置換するサンプルコードを示します。

まず、pages/api/data.tsという API エンドポイントを作成します。

// pages/api/data.ts
import type { NextApiRequest, NextApiResponse } from 'next'
import axios from 'axios'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  const { data } = await axios.get('microCMSのエンドポイントURL', {
    headers: {
      'X-API-KEY': 'microCMSのAPIキー',
    },
  })

  const replacedData = data.map((item: any) => {
    return {
      ...item,
      title: item.title.replace('置換前の単語', '置換後の単語'),
    }
  })

  res.status(200).json(replacedData)
}

export default handler

このコードは、microCMS からデータを非同期に取得し、取得したデータの中の特定の単語を別の単語に置換しています。

ここで replace('置換前の単語', '置換後の単語') という部分が replace() メソッドの使用箇所です。このコードは item.title の中の '置換前の単語' を '置換後の単語' に置換します。

このように、Next.js と TypeScript、そして replace() メソッドを使って、API から取得したデータ内の特定の単語を別の単語に置換することができます。

関数を新しい値として使う

ここでは、さらに高度な replace() メソッドの使用例を見ていきます。具体的には、関数を新しい値として使って特定のパターンを置き換える方法を見てみましょう。

components/AdvancedGreeting.tsx

import React from 'react'

type Props = {
  greeting: string
}

const AdvancedGreeting = ({ greeting }: Props) => {
  const replaceFunction = () => {
    return greeting.replace(/世界/g, (match) => {
      return match === '世界' ? 'Next.jsユーザー' : '世界'
    })
  }

  return <h1>{replaceFunction()}</h1>
}

export default AdvancedGreeting

pages/advanced.tsx

import AdvancedGreeting from '../components/AdvancedGreeting'

const AdvancedHome = () => {
  return <AdvancedGreeting greeting="こんにちは、世界" />
}

export default AdvancedHome

ここでは、replace() メソッドに関数を渡しています。この関数は、マッチしたパターンごとに呼び出され、その返り値がマッチしたパターンの新しい値となります。このようにすることで、より高度な文字列の置き換え処理が可能となります。

JavaScript:文字列を置換するreplace()を極める