---
type: learn
language: javascript
slug: string/search
title: "文字列を探す・分ける・置き換える"
title_tag: "JavaScript 文字列の検索と置換 — includes と split【第3回】"
summary: >
  includes() と indexOf() の使い分け、-1 が返る理由と 0 が falsy になる落とし穴、
  大文字小文字を無視した検索、split() と join() での分解と組み立てを実行して確かめます。
description: >
  if に indexOf をそのまま書くと、先頭で見つかっても「無い」と判定されます。includes との使い分け、大文字小文字を無視する正しい書き方、split の意外な挙動まで扱います。
status: published
difficulty: 2
minutes: 10

versions:
  verified: "Node 22.22.3"
  since: "ES2015"
  deprecated: null
  removed: null

sources:
  - title: "String.prototype.includes — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-string.prototype.includes"
  - title: "String.prototype.indexOf — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-string.prototype.indexof"
  - title: "String.prototype.split — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split"

terms: [部分文字列, falsy, 区切り文字, 大文字小文字の畳み込み]

links:
  prev: javascript/learn/string/slice
  next: javascript/learn/string/unicode
  related:
    - javascript/reference/string/split
    - javascript/reference/string/replace
    - javascript/reference/regexp/test-match

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

「この文字が入っているか」を知りたいだけなら `includes()` です。**[key:真偽値]が返ります。**

```js run
const title = 'プログラミング大全';

console.log(title.includes('大全'));
console.log(title.includes('入門'));
```
```output
true
false
```

`if` にそのまま書けるので、**あるか無いかだけ知りたいときはこれが最短です。**

## 位置まで知りたいときは `indexOf()`

見つかった[type:添字]を返します。

```js run
const title = 'プログラミング大全';

console.log(title.indexOf('大全'));
console.log(title.indexOf('プロ'));
```
```output
7
0
```

無いときは[num:-1]を返します。

```js run
console.log('プログラミング大全'.indexOf('入門'));
```
```output
-1
```

**なぜ `-1` なのか。** 添字は[num:0]から始まるので、`0` は「先頭で見つかった」という[em:正しい答え]です。
「無い」を表すには、添字としてありえない値が要ります。それが `-1` です。

### ここが落とし穴

`indexOf()` の結果を、そのまま `if` に書いてはいけません。

```js bad
const title = 'プログラミング大全';

if (title.indexOf('プロ')) {
  console.log('見つかった');
} else {
  console.log('見つからなかった');
}
```
```output
見つからなかった
```

**先頭にあるのに、無いと判定されました。**
`indexOf('プロ')` は `0` を返し、`0` は[type:falsy]（偽として扱われる値）だからです。

書くなら[key:比較を省かない]でください。

```js run
const title = 'プログラミング大全';

if (title.indexOf('プロ') !== -1) {
  console.log('見つかった');
}
```
```output
見つかった
```

**あるか無いかだけなら `includes()` を使えば、この間違いは起きません。**
`indexOf()` は[em:位置が要るときだけ]使ってください。

## 先頭・末尾だけ調べる

```js run
const file = 'report-2026.pdf';

console.log(file.startsWith('report'));
console.log(file.endsWith('.pdf'));
console.log(file.lastIndexOf('-'));
```
```output
true
true
6
```

`lastIndexOf()` は[fn:後ろから探して]、最後に見つかった位置を返します。
拡張子やディレクトリの区切りを探すときに使います。

## 大文字と小文字を区別する

検索は[key:1文字ずつそのまま]比べます。大文字と小文字は別の文字です。

```js run
const word = 'JavaScript';

console.log(word.includes('script'));
console.log(word.includes('Script'));
```
```output
false
true
```

無視したいときは、**両方を同じ側に揃えてから**比べます。

```js run
const word = 'JavaScript';
const keyword = 'SCRIPT';

console.log(word.toLowerCase().includes(keyword.toLowerCase()));
```
```output
true
```

[bad:片方だけ変換すると、もう片方が大文字のときに外れます]。必ず両方を揃えてください。

### 大文字にすると長さが変わることがある

```js run
const word = 'Straße';

console.log(word.length);
console.log(word.toUpperCase());
console.log(word.toUpperCase().length);
```
```output
6
STRASSE
7
```

ドイツ語の `ß` は、大文字にすると `SS` の[num:2]文字になります。
**文字数が変わらない前提でコードを書かないでください。**
[dim:半角カタカナのように、大文字小文字の区別が無くて何も変わらない文字もあります。]

## 区切って配列にする

`split()` は[type:区切り文字]で分けて配列にします。

```js run
console.log('2026-09-08'.split('-'));
console.log('りんご,みかん,ぶどう'.split(','));
```
```output
[ '2026', '09', '08' ]
[ 'りんご', 'みかん', 'ぶどう' ]
```

見つからないときも[bad:空にはなりません]。元の文字列が1つだけ入った配列が返ります。

```js run
console.log('見つからない'.split(','));
```
```output
[ '見つからない' ]
```

区切りが続いていると、間に[type:空文字列]が入ります。

```js run
console.log('a,,b'.split(','));
```
```output
[ 'a', '', 'b' ]
```

**これは不具合ではありません。** 「区切りが2つあるので、間に空の項目がある」という素直な結果です。
→ [split() の詳しい挙動](/ja/javascript/reference/string/split/)

### 分けたあとに整える

入力を分けると、たいてい前後に空白が残ります。[第2回](/ja/javascript/learn/string/slice/)の `trim()` と組み合わせます。

```js run
const input = '  りんご , みかん , ぶどう ';

console.log(input.split(',').map((item) => item.trim()));
```
```output
[ 'りんご', 'みかん', 'ぶどう' ]
```

## つなぎ直す

`join()` は配列を1つの文字列にします。**`split()` の逆です。**

```js run
const fruits = ['りんご', 'みかん', 'ぶどう'];

console.log(fruits.join(' / '));
console.log(fruits.join(''));
console.log([2026, 9, 8].join('-'));
```
```output
りんご / みかん / ぶどう
りんごみかんぶどう
2026-9-8
```

数値の配列でも、[fn:自動で文字列に変えて]つなぎます。

## 置き換える

`replace()` は[bad:最初の1つしか置き換えません]。

```js run
const path = 'a-b-c';

console.log(path.replace('-', '+'));
console.log(path.replaceAll('-', '+'));
```
```output
a+b-c
a+b+c
```

**全部を置き換えたいなら `replaceAll()` です。**
`replace()` の挙動は忘れやすいので、意図が「全部」なら名前で示してください。

置き換える文字列の中で `$` は[key:特別扱い]されます。

```js run
console.log('価格'.replace('価格', '$&円'));
```
```output
価格円
```

`$&` が「見つかった文字列そのもの」に置き換わっています。
[bad:金額を扱うコードで思わぬ結果になります]。
→ [replace() の詳しい挙動](/ja/javascript/reference/string/replace/)

## まとめ

- あるか無いかだけなら `includes()`。**[key:真偽値]が返る**
- 位置が要るときだけ `indexOf()`。無いときは[num:-1]
- **`if (s.indexOf(x))` は間違い。** `0` が[type:falsy]なので先頭を見落とす
- 大文字小文字を無視するなら[em:両方]を揃える。`ß` のように長さが変わる文字がある
- `split()` は見つからなくても[bad:空にならない]。1つ入った配列が返る
- `replace()` は最初の1つだけ。全部なら `replaceAll()`

## 次に学ぶ

ここまで「1文字」という言葉を、深く考えずに使ってきました。
**ですが `length` は、見た目の文字数と一致しないことがあります。**
絵文字や結合文字で何が起きるのか、正しく数えるにはどうするかを学びます。

→ [第4回: 文字を正しく数える](/ja/javascript/learn/string/unicode/)
