「商品ID abc123」や「在庫: 45個」のような文字列から、最初に出てくる数値だけを取り出したい場面があります。JavaScriptでは正規表現を使うのが基本ですが、parseInt との違いを理解しておかないと、想定外の NaN に悩まされます。
str.match(/\d+/)?.[0]、先頭が数値だと分かっているときだけ parseInt(str) が使えます。parseInt は先頭からしか読まないため、parseInt("abc123") は NaN になる点に注意します。match() で最初の数値を抽出する(基本)
もっとも確実な方法です。/\d+/(グローバルフラグ g なし)で match() すると、最初に見つかった連続する数字が 配列の0番目に入ります。?.[0] で安全に取り出し、Number() で数値に変換します。
const str = "商品abc123def456"; const first = str.match(/\d+/)?.[0]; console.log(first); // "123"(文字列) console.log(Number(first)); // 123(数値)
g を付けないのがポイントです。g を付けると全件の配列になりますが、最初の1個だけ欲しいときは /\d+/ のままで [0] を取れば十分です。すべての数値が必要なら文字列から数値のみ取得する方法を参照してください。null:数字が1つも無いとき str.match(/\d+/) は null を返します。そのまま [0] を付けるとエラーになるため、?.[0](オプショナルチェーン)で受け、必要なら ?? null で既定値を決めます。const str = "数字なし"; console.log(str.match(/\d+/)); // null console.log(str.match(/\d+/)?.[0] ?? null); // null(安全)
parseInt() は「先頭が数値」のときだけ使える
parseInt(str) は手軽ですが、文字列の先頭から数値として読める部分だけを返します。先頭が数字なら使えますが、数字より前に文字があると NaN になります。
console.log(parseInt("123abc")); // 123(先頭が数値 → OK)
console.log(parseInt(" 123abc")); // 123(先頭の空白は無視される)
console.log(parseInt("abc123def")); // NaN(先頭が文字 → 取れない!)
parseInt("abc123") は 123 ではなく NaN を返します。どこにあっても拾いたいなら match(/\d+/) を使ってください。小数やマイナス符号を含む最初の数値を取る
\d+ は整数の連続にしかマッチしないため、-3.5 のような値は符号や小数点で切れてしまいます。/-?\d+(?:\.\d+)?/ に広げれば、マイナスや小数を含む最初の数値を取り出せます。
const str = "気温は-3.5度です"; const first = str.match(/-?\d+(?:\.\d+)?/)?.[0]; console.log(first); // "-3.5" console.log(Number(first)); // -3.5
最初の数値の位置(index)も取得する
g フラグなしの match() の戻り値には、マッチした位置 index が含まれます。「何文字目から数値が始まるか」を知りたいときに使えます。
const str = "abc123def"; const m = str.match(/\d+/); console.log(m[0]); // "123" console.log(m.index); // 3(0始まりで4文字目から)
1文字ずつ処理する方法と落とし穴
正規表現を使わず1文字ずつ調べることもできますが、2つの落とし穴があります。①最初の数字を見つけて即 break すると1桁しか取れない("abc123" が "1" になる)、②!isNaN(c) で判定すると isNaN(" ") が false のため空白を数字とみなす。この2点を直したのが次のコードです。
const str = "abc123def456";
let buf = "";
let first = null;
for (const c of str) {
if (c >= "0" && c <= "9") { // 範囲で判定(空白に惑わされない)
buf += c; // 連続する桁をためる
} else if (buf !== "") {
first = buf; // 数字が途切れたら確定
break;
}
}
if (first === null && buf !== "") first = buf; // 末尾で終わるケース
console.log(first); // "123"
str.match(/\d+/)?.[0] の1行で十分です。方法の使い分け
| 状況 | 書き方 |
|---|---|
| どこにあっても最初の数値(推奨) | str.match(/\d+/)?.[0] |
| 先頭が数値だと分かっている | parseInt(str) |
| 小数・マイナスも含める | str.match(/-?\d+(?:\.\d+)?/)?.[0] |
| 出現位置も知りたい | str.match(/\d+/).index |
| すべての数値が欲しい | str.match(/\d+/g) |
実用例:商品名から最初の数量を取り出す
const name = "お徳用12個入りセット"; const qty = Number(name.match(/\d+/)?.[0] ?? 0); console.log(qty); // 12
よくある質問(FAQ)
str.match(/\d+/)?.[0] を使います。位置に関係なく最初の連続した数字を返します。数値型にしたいときは Number(...) で囲み、数字が無い場合に備えて ?.[0] ?? null のようにガードします。parseInt は文字列の先頭からしか数値を読まないためです。parseInt("abc123") は先頭が a なので NaN になります。先頭が数字("123abc")なら 123 が取れます。どこにあっても拾いたいときは match(/\d+/) を使ってください。/-?\d+(?:\.\d+)?/ を使います。-? でマイナス符号、(?:\.\d+)? で小数部に対応します。"気温は-3.5度" から -3.5 が取り出せます。g フラグなしの match() の戻り値の index プロパティを見ます。"abc123".match(/\d+/).index は 3(0始まり)です。まとめ
JavaScriptで文字列内の最初の数値を抽出する方法のポイントを整理します。
- 基本は
str.match(/\d+/)?.[0](位置に関係なく拾える) parseInt(str)は先頭が数値のときだけ。"abc123"はNaN- 小数・マイナスは
/-?\d+(?:\.\d+)?/ - 位置は
match(...).indexで取得 - 反復処理は「1桁で
break」「isNaNで空白誤判定」に注意
関連として、文字列から数値のみ取得する方法(すべて)・文字列内の最後にある数値を取得する方法・文字列を数値型に変換する方法もあわせて確認すると、数値の扱いに強くなれます。
