文字列を探す・分ける・置き換える

includes() と indexOf() の使い分け、-1 が返る理由と 0 が falsy になる落とし穴、大文字小文字を無視した検索、split() と join() での分解と組み立てを実行して確かめます。

実行して検証済み処理系Node 22.22.3対応ES2015難易度●●○○○目安10更新

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true false
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
7 0

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

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

見つかった添字を返します。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
-1
javascript
const title = 'プログラミング大全';

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

無いときは-1を返します。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
見つかった
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true true 6

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

ここが落とし穴

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
false true
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true

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

書くなら比較を省かないでください。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
6 STRASSE 7
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ '2026', '09', '08' ] [ 'りんご', 'みかん', 'ぶどう' ]

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

先頭・末尾だけ調べる

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ '見つからない' ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'a', '', 'b' ]

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

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

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'りんご', 'みかん', 'ぶどう' ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
りんご / みかん / ぶどう りんごみかんぶどう 2026-9-8

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
a+b-c a+b+c
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
価格円

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

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

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

区切って配列にする

split()区切り文字で分けて配列にします。

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

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

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

分けたあとに整える

入力を分けると、たいてい前後に空白が残ります。第2回trim() と組み合わせます。

つなぎ直す

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

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

置き換える

replace()最初の1つしか置き換えません

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

置き換える文字列の中で $特別扱いされます。

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

まとめ

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

次に学ぶ

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

第4回: 文字を正しく数える

この記事の根拠

  1. String.prototype.includes — ECMAScript® 2026 Language Specificationtc39.es
  2. String.prototype.indexOf — ECMAScript® 2026 Language Specificationtc39.es
  3. String.prototype.split — MDNdeveloper.mozilla.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)