【初心者向け】JavaScript文字列の切り出し - substring/sliceの使い方
JavaScriptで文字列から一部を切り出す方法を初心者向けに解説。substring、slice、substrメソッドの違いと使い分けを実際のコード例とともに詳しく説明します。
【初心者向け】JavaScript文字列の切り出し - substring/sliceの使い方
みなさん、JavaScriptで文字列を扱っていて「文字列の一部だけを取り出したい」と思ったことありませんか?
「長い文字列から必要な部分だけ取り出したい」 「どのメソッドを使えばいいの?」 「substringとsliceって何が違うの?」
こんな疑問を感じることってありますよね。
実は、JavaScriptには文字列を切り出すメソッドが3つあるんです。 それぞれに特徴があって、場面によって使い分けることで効率的なコードが書けます。
この記事では、JavaScript の文字列切り出しメソッドについて、基本的な使い方から実践的な活用例まで詳しく解説します。 どのメソッドをいつ使えばいいのかも分かりやすく説明していきますよ。
文字列切り出しって何?
どんな時に使うのか
文字列の切り出しは、Webアプリケーションでよく使われる処理です。 実際のプログラムで使われる場面を見てみましょう。
// ユーザー名の表示(長い名前を短縮)let fullName = "田中太郎さん";let shortName = fullName.substring(0, 3); // "田中太"
// ファイル名から拡張子を取得let fileName = "document.pdf";let extension = fileName.slice(-3); // "pdf"
// URLからドメイン名を抽出let url = "https://example.com/page";let domain = url.substring(8, 19); // "example.com"
このように、文字列の一部を取り出すことで、データの整形や表示の調整ができます。
文字列のインデックスを理解しよう
文字列切り出しを理解するために、文字列のインデックス(位置)について確認しましょう。
let text = "Hello";
// インデックスは0から始まる// H e l l o// 0 1 2 3 4
console.log(text[0]); // "H"console.log(text[1]); // "e"console.log(text[4]); // "o"
JavaScriptの文字列は、0から始まる番号で各文字にアクセスできます。 これは文字列操作の基本なので、覚えておきましょう。
substring()メソッドの使い方
基本的な構文
最も基本的な文字列切り出しメソッドです。
文字列.substring(開始位置, 終了位置)
終了位置は含まれないことに注意してください。
基本的な使用例
let text = "JavaScript";
// 位置2から位置6まで(6は含まない)console.log(text.substring(2, 6)); // "vaS"
// 位置0から位置4までconsole.log(text.substring(0, 4)); // "Java"
// 位置5から最後までconsole.log(text.substring(5)); // "cript"
第二引数を省略すると、文字列の最後まで切り出されます。 これはとても便利な機能ですね。
substringの特徴
substringメソッドには特殊な仕様があります。
let text = "Programming";
// 引数が逆でも自動的に修正されるconsole.log(text.substring(5, 2)); // "ogr"(2から5として処理)console.log(text.substring(2, 5)); // "ogr"(同じ結果)
// 負の値は0として扱われるconsole.log(text.substring(-3, 5)); // "Progr"(0から5として処理)console.log(text.substring(0, 5)); // "Progr"(同じ結果)
この自動修正機能により、エラーが起きにくい反面、予期しない結果になることがあります。
実践的な使用例
// メールアドレスからユーザー名を取得function getUserName(email) { let atIndex = email.indexOf("@"); if (atIndex !== -1) { return email.substring(0, atIndex); } return email;}
console.log(getUserName("user@example.com")); // "user"console.log(getUserName("invalid-email")); // "invalid-email"
メールアドレスから@マークより前の部分を取り出しています。 @が見つからない場合は、元の文字列をそのまま返します。
// 文字列の最初の数文字を取得function getPreview(text, length) { if (text.length <= length) { return text; } return text.substring(0, length) + "...";}
console.log(getPreview("これは長いテキストです", 5)); // "これは長い..."console.log(getPreview("短いテキスト", 10)); // "短いテキスト"
長いテキストを短く表示する時によく使われるパターンです。
slice()メソッドの使い方
基本的な構文
より柔軟な文字列切り出しができるメソッドです。
文字列.slice(開始位置, 終了位置)
substringと似ていますが、動作が異なります。
基本的な使用例
let text = "JavaScript";
// 基本的な切り出しconsole.log(text.slice(2, 6)); // "vaS"console.log(text.slice(0, 4)); // "Java"console.log(text.slice(5)); // "cript"
基本的な使い方はsubstringと同じです。
sliceの特徴:負のインデックス
sliceの最大の特徴は、負のインデックスが使えることです。
let text = "Programming";
// 負のインデックスで末尾から指定console.log(text.slice(-4)); // "ming"(末尾4文字)console.log(text.slice(-7, -3)); // "ramm"(末尾7文字目から末尾3文字目まで)console.log(text.slice(0, -3)); // "Programm"(最初から末尾3文字を除く)
負のインデックスを使うと、末尾からの位置指定が簡単にできます。
// substringとの違いconsole.log(text.substring(-4)); // "Programming"(負の値は0として扱われる)console.log(text.slice(-4)); // "ming"(末尾から4文字)
この違いを覚えておくと、適切にメソッドを選択できます。
sliceの厳密性
sliceは引数の順序を自動修正しません。
let text = "Hello";
// 引数の順序が逆の場合console.log(text.substring(3, 1)); // "el"(自動修正される)console.log(text.slice(3, 1)); // ""(空文字列)
// 開始位置が終了位置より大きい場合、sliceは空文字列を返すconsole.log(text.slice(4, 2)); // ""
この厳密性により、より予測可能な動作をします。
実践的な使用例
// ファイル名から拡張子を取得function getFileExtension(fileName) { let dotIndex = fileName.lastIndexOf("."); if (dotIndex !== -1) { return fileName.slice(dotIndex + 1); } return "";}
console.log(getFileExtension("document.pdf")); // "pdf"console.log(getFileExtension("image.jpg")); // "jpg"console.log(getFileExtension("file")); // ""
最後のドット以降を拡張子として取得しています。
// URLの最後のパスを取得function getLastPath(url) { // 末尾のスラッシュを除去 let cleanUrl = url.endsWith("/") ? url.slice(0, -1) : url; let lastSlashIndex = cleanUrl.lastIndexOf("/"); if (lastSlashIndex !== -1) { return cleanUrl.slice(lastSlashIndex + 1); } return cleanUrl;}
console.log(getLastPath("https://example.com/users/profile")); // "profile"console.log(getLastPath("https://example.com/api/")); // "api"
sliceの柔軟性を活用した実用的な例です。
substr()メソッドの使い方
基本的な構文
位置と長さで切り出しを行うメソッドです。
文字列.substr(開始位置, 長さ)
他のメソッドと異なり、第二引数は「長さ」を指定します。
基本的な使用例
let text = "JavaScript";
// 位置2から3文字分console.log(text.substr(2, 3)); // "vaS"
// 位置0から4文字分console.log(text.substr(0, 4)); // "Java"
// 位置5から最後までconsole.log(text.substr(5)); // "cript"
長さで指定するため、直感的に理解しやすい場合があります。
substrの特徴
let text = "Programming";
// 負の開始位置(末尾からの位置)console.log(text.substr(-4, 2)); // "mi"(末尾4文字目から2文字)console.log(text.substr(-6)); // "amming"(末尾6文字目から最後まで)
// 長さが文字列を超える場合console.log(text.substr(5, 100)); // "amming"(可能な限り切り出し)
負の開始位置は使えますが、負の長さは意味がありません。
重要な注意点
重要: substr()メソッドは非推奨(deprecated)とされています。
// 推奨されないlet result = text.substr(2, 3);
// 代替案: sliceを使用let result = text.slice(2, 2 + 3); // slice(開始, 開始+長さ)
// または関数を作成function substr(str, start, length) { return str.slice(start, start + length);}
新しいコードではsliceやsubstringの使用を推奨します。
メソッドの比較と使い分け
機能比較表
各メソッドの特徴を比較してみましょう。
機能 | substring | slice | substr |
---|---|---|---|
基本的な切り出し | ○ | ○ | ○ |
負のインデックス | × | ○ | △(開始位置のみ) |
引数の自動修正 | ○ | × | × |
第二引数の意味 | 終了位置 | 終了位置 | 長さ |
推奨度 | ○ | ○ | × |
具体的な比較例
let text = "Hello World";
// 同じ結果を得る異なる方法console.log("=== 'Hello'を取得 ===");console.log(text.substring(0, 5)); // "Hello"console.log(text.slice(0, 5)); // "Hello"console.log(text.substr(0, 5)); // "Hello"
console.log("=== 'World'を取得 ===");console.log(text.substring(6, 11)); // "World"console.log(text.slice(6, 11)); // "World"console.log(text.slice(-5)); // "World"(負のインデックス使用)console.log(text.substr(6, 5)); // "World"
同じ結果でも、書き方が変わります。 場面に応じて最適な方法を選びましょう。
console.log("=== 異常な引数での動作 ===");console.log(text.substring(5, 2)); // "llo"(自動修正)console.log(text.slice(5, 2)); // ""(空文字列)
エラーハンドリングの観点でも違いがあります。
使い分けの指針
基本的な判断基準をまとめました。
substring を使う場面:
- 安全性を重視する場合
- 引数の順序が不明確な場合
- エラーを避けたい初心者向けコード
slice を使う場面:
- 負のインデックスを使いたい場合
- より厳密な動作を求める場合
- 現代的なJavaScriptコード
substr を使う場面:
- 使用を避ける(非推奨のため)
実践的な選択例
// ケース1: 安全な文字列切り出しfunction safeSubstring(str, start, end) { return str.substring(start, end);}
// ケース2: 末尾からの切り出しfunction getLastCharacters(str, count) { return str.slice(-count);}
// ケース3: 柔軟な切り出しfunction flexibleSlice(str, start, end = str.length) { if (start < 0) start = str.length + start; if (end < 0) end = str.length + end; return str.slice(start, end);}
// 使用例let text = "JavaScript Programming";console.log(safeSubstring(text, 0, 10)); // "JavaScript"console.log(getLastCharacters(text, 11)); // "Programming"console.log(flexibleSlice(text, -11, -1)); // "Programmin"
用途に応じて最適な方法を選択できます。
実践的な応用例
テキストの省略表示
function truncateText(text, maxLength, suffix = "...") { if (text.length <= maxLength) { return text; } // 単語の途中で切れないように調整 let truncated = text.substring(0, maxLength); let lastSpace = truncated.lastIndexOf(" "); if (lastSpace > maxLength * 0.8) { truncated = truncated.substring(0, lastSpace); } return truncated + suffix;}
// 使用例let longText = "これは非常に長いテキストの例です。適切な長さで切り詰める必要があります。";console.log(truncateText(longText, 20)); // "これは非常に長いテキスト..."
ブログの記事プレビューなどでよく使われる機能です。 単語の途中で切れないように配慮しています。
データの解析と抽出
// 日付文字列の解析function parseDate(dateString) { // "2024-01-15" の形式を解析 if (dateString.length === 10 && dateString.includes("-")) { return { year: dateString.substring(0, 4), month: dateString.substring(5, 7), day: dateString.substring(8, 10) }; } return null;}
// クレジットカード番号のマスクfunction maskCreditCard(cardNumber) { if (cardNumber.length < 4) return cardNumber; let lastFour = cardNumber.slice(-4); let masked = "*".repeat(cardNumber.length - 4); return masked + lastFour;}
// 使用例console.log(parseDate("2024-01-15")); // {year: "2024", month: "01", day: "15"}console.log(maskCreditCard("1234567890123456")); // "************3456"
日付の解析にはsubstring、セキュリティ関連の処理にはsliceを使っています。
URLやパスの処理
// URLからクエリパラメータを抽出function extractQueryParams(url) { let queryStart = url.indexOf("?"); if (queryStart === -1) return {}; let queryString = url.slice(queryStart + 1); let params = {}; queryString.split("&").forEach(pair => { let [key, value] = pair.split("="); if (key) { params[key] = value || ""; } }); return params;}
// ファイルパスの操作function getFileName(path) { let fileName = path.slice(path.lastIndexOf("/") + 1); let dotIndex = fileName.lastIndexOf("."); return { name: dotIndex !== -1 ? fileName.substring(0, dotIndex) : fileName, extension: dotIndex !== -1 ? fileName.slice(dotIndex + 1) : "" };}
// 使用例console.log(extractQueryParams("https://example.com?page=1&size=10")); // {page: "1", size: "10"}
console.log(getFileName("/path/to/document.pdf")); // {name: "document", extension: "pdf"}
URLやファイルパスの処理では、sliceとsubstringを使い分けています。
安全な文字列処理のコツ
入力値の検証
function safeStringExtraction(str, start, end) { // 入力値の検証 if (typeof str !== "string") { return ""; } if (typeof start !== "number" || start < 0) { start = 0; } if (typeof end !== "number" || end > str.length) { end = str.length; } // 開始位置が終了位置より大きい場合の処理 if (start >= end) { return ""; } return str.slice(start, end);}
// 使用例console.log(safeStringExtraction("Hello", 1, 4)); // "ell"console.log(safeStringExtraction("Hello", -1, 3)); // "Hel"console.log(safeStringExtraction("Hello", 3, 1)); // ""console.log(safeStringExtraction(null, 0, 3)); // ""
予期しない入力に対してもエラーを出さない安全な実装です。
パフォーマンスの考慮
// 大量の文字列処理を行う場合function processLargeText(text, chunkSize = 1000) { let results = []; for (let i = 0; i < text.length; i += chunkSize) { let chunk = text.slice(i, i + chunkSize); // チャンクの処理 results.push(processChunk(chunk)); } return results;}
function processChunk(chunk) { // 実際の処理をここに記述 return chunk.toUpperCase();}
大きなテキストを処理する時は、小さな単位に分けて処理するとメモリ効率が良くなります。
まとめ
JavaScript の文字列切り出しメソッドについて詳しく解説しました。
主要メソッドの特徴:
- substring: 安全で自動修正機能あり、初心者向け
- slice: 負のインデックス対応、現代的で推奨
- substr: 非推奨、新しいコードでは使用を避ける
使い分けの指針:
- 基本的な切り出し → substring
- 末尾からの切り出し → slice
- 厳密な動作が必要 → slice
- 安全性を重視 → substring
実践でのポイント:
- 入力値の検証を忘れずに
- 負のインデックスを活用
- パフォーマンスを考慮した実装
- エラーハンドリングの実装
文字列の切り出しは、データ処理やユーザーインターフェース開発で頻繁に使われる重要な技術です。 各メソッドの特徴を理解して適切に使い分けることで、より効率的で保守しやすいコードが書けるようになります。
ぜひ今日から、文字列切り出しメソッドを使った実践的なプログラムに挑戦してみてください!