JavaScriptで文字列を句読点(、。! ? など)で分割したいケースは、テキスト処理・自然言語処理・チャットUI・字幕生成など多くの実務場面で登場します。
この記事では、split() メソッドの基本から、正規表現を使った高度な分割、区切り文字を残す方法、最新の Intl.Segmenter API まで、句読点分割のすべてを網羅的に解説します。
この記事で学べること
split() と正規表現で句読点ごとに文字列を分割する基本
- 日本語(、。)・英語(. , ! ?)それぞれの分割パターン
- 複数の区切り文字で同時に分割するテクニック
- 区切り文字を結果に残す方法(先読み・後読み・キャプチャグループ)
- 空要素の除去と
matchAll() を使った高度な分割
Intl.Segmenter による最新の文分割 API
- 実務での活用例(テキスト要約・チャット表示・字幕分割)
split() メソッドの基本 ― 正規表現で句読点分割
String.prototype.split() は、指定した区切り文字(または正規表現)で文字列を分割し、配列として返すメソッドです。句読点での分割には正規表現を使うのが最も柔軟です。
JavaScript – split() の基本構文
// 文字列.split(区切り文字 or 正規表現, 最大分割数)
const text = "Hello, world. How are you?";
// 文字列で分割(1種類のみ)
const arr1 = text.split(".");
// ["Hello, world", " How are you?"]
// 正規表現で分割(複数種類 OK)
const arr2 = text.split(/[.,?]/);
// ["Hello", " world", " How are you", ""]
実行結果
arr1 → ["Hello, world", " How are you?"]
arr2 → ["Hello", " world", " How are you", ""]
注意:正規表現で分割すると、区切り文字の直後が文字列末尾の場合に空文字 "" が配列に含まれます。後述の filter() で除去できます。
日本語の句読点(、。)で文字列を分割する
日本語テキストを扱う場合、全角の句点 。 と読点 、 で分割するパターンが最も一般的です。
JavaScript – 日本語句読点で分割
const text = "今日は天気が良い。散歩に出かけよう。公園で、花を見た。";
// 句点(。)のみで分割
const sentences = text.split("。");
console.log(sentences);
// 句点・読点の両方で分割
const parts = text.split(/[、。]/);
console.log(parts);
実行結果
sentences → ["今日は天気が良い", "散歩に出かけよう", "公園で、花を見た", ""]
parts → ["今日は天気が良い", "散歩に出かけよう", "公園で", "花を見た", ""]
英語のピリオド・カンマ・感嘆符で分割する
英語テキストでは .(ピリオド)、,(カンマ)、!(感嘆符)、?(疑問符)が主な句読点です。
JavaScript – 英語の句読点で分割
const text = "Hello, world! How are you? I am fine.";
// 主要な英語句読点で分割
const result = text.split(/[.!?,]/);
console.log(result);
// 句読点 + 後続スペースもまとめて分割
const clean = text.split(/[.!?,]\s*/).filter(Boolean);
console.log(clean);
実行結果
result → ["Hello", " world", " How are you", " I am fine", ""]
clean → ["Hello", "world", "How are you", "I am fine"]
ポイント:/[.!?,]\s*/ のように句読点の後の空白 \s* も含めて分割すると、各要素の先頭に不要なスペースが残りません。
複数の区切り文字で同時に分割する(日本語+英語混在)
実務では日本語と英語が混在するテキストを扱うことが多いため、全角・半角の句読点をまとめて正規表現の文字クラス [] に指定します。
JavaScript – 複数句読点で同時に分割
const text = "今日はJavaScriptを学ぶ。split()は便利だ、本当に!Really?Yes.";
// 日本語+英語の句読点すべてで分割
const pattern = /[、。,.,.!?!?;;::]+/;
const result = text.split(pattern).filter(Boolean);
console.log(result);
実行結果
["今日はJavaScriptを学ぶ", "split()は便利だ", "本当に", "Really", "Yes"]
よく使う句読点パターン一覧
| 正規表現パターン |
対象 |
説明 |
/[。]/ |
日本語 |
句点のみ |
/[、。]/ |
日本語 |
句点+読点 |
/[.!?,]/ |
英語 |
ピリオド・感嘆符・疑問符・カンマ |
/[、。,.!?!?]+/ |
混在 |
日英の主要句読点すべて |
/[、。,.,.!?!?;;::]+/ |
混在(全網羅) |
セミコロン・コロンも含む完全版 |
区切り文字を残したまま分割する方法
通常の split() では区切り文字は結果から除去されます。しかし、「。」や「!」を残したまま文を分割したいケースは非常に多いです。3つの方法を紹介します。
方法1: キャプチャグループ () を使う
split() の正規表現にキャプチャグループ () を使うと、マッチした区切り文字も配列の要素として残ります。
JavaScript – キャプチャグループで区切り文字を残す
const text = "今日は天気が良い。散歩に行こう!楽しみだ。";
// キャプチャグループ () で区切り文字を配列に残す
const parts = text.split(/([。!])/);
console.log(parts);
// 区切り文字を前の要素に結合して復元
const sentences = [];
for (let i = 0; i < parts.length; i += 2) {
const sentence = parts[i] + (parts[i + 1] || '');
if (sentence) sentences.push(sentence);
}
console.log(sentences);
実行結果
parts → ["今日は天気が良い", "。", "散歩に行こう", "!", "楽しみだ", "。", ""]
sentences → ["今日は天気が良い。", "散歩に行こう!", "楽しみだ。"]
方法2: 先読み(lookahead)で分割位置を指定
肯定先読み (?=...) を使うと、区切り文字の直前で分割できます。区切り文字は次の要素の先頭に残ります。
JavaScript – 先読みで分割
const text = "今日は天気が良い。散歩に行こう!楽しみだ。";
// 句読点の直前で分割(句読点は次の要素の先頭に残る)
const result = text.split(/(?=[。!?])/);
console.log(result);
実行結果
["今日は天気が良い", "。散歩に行こう", "!楽しみだ", "。"]
方法3: 後読み(lookbehind)で分割 ― 句読点を前の要素に残す
肯定後読み (?<=...) を使うと、区切り文字の直後で分割されます。句読点は前の要素の末尾に残るため、最も自然な文分割になります。
JavaScript – 後読みで分割(推奨)
const text = "今日は天気が良い。散歩に行こう!楽しみだ。";
// 句読点の直後で分割(句読点は前の要素の末尾に残る)
const result = text.split(/(?<=[。!?])/).filter(Boolean);
console.log(result);
実行結果
["今日は天気が良い。", "散歩に行こう!", "楽しみだ。"]
ポイント:後読み (?<=...) を使えば「今日は天気が良い。」のように句読点付きの完全な文として分割できるため、チャット表示や字幕分割に最適です。
3つの方法の比較
| 方法 |
正規表現 |
区切り文字の位置 |
用途 |
| キャプチャグループ |
/([。!])/ |
独立した要素 |
後処理で結合する場合 |
| 先読み |
/(?=[。!])/ |
次の要素の先頭 |
区切り文字が次文の一部の場合 |
| 後読み(推奨) |
/(?<=[。!])/ |
前の要素の末尾 |
自然な文分割 |
空要素の除去 ― filter(Boolean) の活用
split() の結果には空文字 "" が含まれることがあります。filter(Boolean) で簡潔に除去できます。
JavaScript – 空要素の除去
const text = "Hello. World. ";
// split の結果に空文字が含まれる
const raw = text.split(".");
console.log(raw);
// ["Hello", " World", " "]
// filter(Boolean) で空文字・空白のみの要素を除去
const cleaned = text.split(".")
.map(s => s.trim())
.filter(Boolean);
console.log(cleaned);
// ["Hello", "World"]
実行結果
raw → ["Hello", " World", " "]
cleaned → ["Hello", "World"]
filter(Boolean) の仕組み
Boolean("") は false → 空文字を除去
Boolean("Hello") は true → 文字列を残す
.map(s => s.trim()) と組み合わせると、空白のみの要素も除去できる
matchAll() を使った高度な句読点分割
split() の代わりに matchAll() を使うと、区切り文字の位置情報(index)も同時に取得でき、より柔軟な分割処理が可能です。
JavaScript – matchAll() で句読点付きの文を抽出
const text = "今日は天気が良い。明日は雨らしい!傘を持とう。";
// 句読点で終わる文をまとめて抽出
const pattern = /[^。!?]+[。!?]/g;
const matches = [...text.matchAll(pattern)];
matches.forEach(m => {
console.log(`文: "${m[0]}" 位置: ${m.index}`);
});
実行結果
文: "今日は天気が良い。" 位置: 0
文: "明日は雨らしい!" 位置: 9
文: "傘を持とう。" 位置: 17
matchAll() はマッチごとの位置(index)も返すため、テキストエディタでの強調表示や、分割位置のデバッグに便利です。
文章の区切り位置を検出する
テキスト処理では「どこで文が区切られるか」という位置情報が必要になるケースがあります。matchAll() と組み合わせた実装を紹介します。
JavaScript – 区切り位置検出ユーティリティ
/**
* テキスト内の句読点位置をすべて検出する
* @param {string} text - 入力テキスト
* @param {RegExp} punctuation - 句読点パターン
* @returns {Array} 位置情報の配列
*/
function findBreakPoints(text, punctuation = /[。!?.!?]/g) {
const points = [];
let match;
while ((match = punctuation.exec(text)) !== null) {
points.push({
char: match[0],
index: match.index,
sentence: text.slice(
points.length ? points[points.length - 1].index + 1 : 0,
match.index + 1
).trim()
});
}
return points;
}
const text = "JavaScriptは楽しい。学ぶことが多い!頑張ろう。";
const breaks = findBreakPoints(text);
console.table(breaks);
実行結果
┌─────────┬──────┬───────┬──────────────────────┐
│ (index) │ char │ index │ sentence │
├─────────┼──────┼───────┼──────────────────────┤
│ 0 │ '。' │ 10 │ 'JavaScriptは楽しい。' │
│ 1 │ '!' │ 18 │ '学ぶことが多い!' │
│ 2 │ '。' │ 23 │ '頑張ろう。' │
└─────────┴──────┴───────┴──────────────────────┘
Intl.Segmenter で文を分割する(最新API)
Intl.Segmenter は、ECMAScript 国際化 API に含まれる言語対応のテキスト分割 API です。正規表現に頼らず、言語のルールに基づいて文(sentence)・単語(word)・書記素(grapheme)単位で分割できます。
JavaScript – Intl.Segmenter で文分割
// 日本語テキストを文単位で分割
const segmenter = new Intl.Segmenter("ja", { granularity: "sentence" });
const text = "今日は天気が良い。散歩に行こう!公園で花を見た。";
const segments = [...segmenter.segment(text)];
segments.forEach(seg => {
console.log(`[${seg.index}] "${seg.segment}"`);
});
// 文の配列として取得
const sentences = segments.map(s => s.segment);
console.log(sentences);
実行結果
[0] "今日は天気が良い。"
[9] "散歩に行こう!"
[16] "公園で花を見た。"
sentences → ["今日は天気が良い。", "散歩に行こう!", "公園で花を見た。"]
英語テキストでの Intl.Segmenter
JavaScript – 英語テキストの文分割
const segmenter = new Intl.Segmenter("en", { granularity: "sentence" });
const text = "Hello world. How are you? I am fine!";
const sentences = [...segmenter.segment(text)].map(s => s.segment.trim());
console.log(sentences);
// ["Hello world.", "How are you?", "I am fine!"]
Intl.Segmenter のメリット
- 正規表現が不要で、言語ルールに基づいた正確な分割が可能
- 「Mr. Smith」のような略語のピリオドを文の区切りと誤認しない
"sentence"、"word"、"grapheme" の3つの粒度で分割可能
- 多言語対応(日本語・英語・中国語・韓国語など)
ブラウザ互換性
各メソッドのブラウザ対応状況を確認しておきましょう。
| 機能 |
Chrome |
Firefox |
Safari |
Edge |
Node.js |
split() |
1+ |
1+ |
1+ |
12+ |
全バージョン |
後読み (?<=...) |
62+ |
78+ |
16.4+ |
79+ |
8.10+ |
matchAll() |
73+ |
67+ |
13+ |
79+ |
12.0+ |
Intl.Segmenter |
87+ |
125+ |
15.4+ |
87+ |
16.0+ |
注意:Intl.Segmenter は Firefox 125+(2024年4月リリース)で対応されましたが、古いブラウザでは使用できません。IE では非対応のため、レガシー環境では split() + 正規表現を使いましょう。
実務での活用例
句読点分割は多くの実務シーンで活用されています。代表的な3つのユースケースを紹介します。
活用例1: テキスト要約の前処理
AI やテキスト要約ツールに文章を渡す前に、文単位に分割して重要度スコアを付ける前処理に使えます。
JavaScript – テキスト要約の前処理
function preprocessForSummary(text, maxSentences = 3) {
// 文単位に分割
const sentences = text.split(/(?<=[。!?.!?])/)
.map(s => s.trim())
.filter(Boolean);
// 各文のスコアを計算(文字数ベースの簡易版)
const scored = sentences.map(s => ({
text: s,
score: s.length // 実務ではTF-IDFなどを使用
}));
// スコア上位の文を抽出
return scored
.sort((a, b) => b.score - a.score)
.slice(0, maxSentences)
.map(s => s.text);
}
const article = "JavaScriptは人気の言語です。Webフロントエンドの開発に不可欠です。サーバーサイドでも使われています。初心者にもおすすめの言語です。";
console.log(preprocessForSummary(article, 2));
実行結果
["Webフロントエンドの開発に不可欠です。", "サーバーサイドでも使われています。"]
活用例2: チャット風の逐次表示(タイプライター効果)
チャットボットやAI応答の表示で、文ごとに少し間を空けて表示するタイプライター効果の実装です。
JavaScript – チャット風の逐次表示
async function typewriterBysentence(text, container) {
// 句読点ごとに分割(区切り文字を残す)
const sentences = text.split(/(?<=[。!?.!?])/).filter(Boolean);
for (const sentence of sentences) {
const span = document.createElement("span");
span.textContent = sentence;
span.style.opacity = "0";
span.style.transition = "opacity 0.5s";
container.appendChild(span);
// フェードイン
await new Promise(r => setTimeout(r, 100));
span.style.opacity = "1";
// 次の文まで待機
await new Promise(r => setTimeout(r, 800));
}
}
// 使用例
const el = document.getElementById("chat-output");
typewriterBysentence("了解しました。処理を開始します。少々お待ちください。", el);
活用例3: 字幕・キャプションの分割
動画の字幕やプレゼンテーションのキャプションを適切な長さに分割するユーティリティです。
JavaScript – 字幕用テキスト分割
/**
* 字幕用にテキストを最大文字数で分割する
* 句読点の位置で優先的に区切る
*/
function splitForSubtitles(text, maxChars = 20) {
// まず句読点で分割
const sentences = text.split(/(?<=[。、!?.!?,])/).filter(Boolean);
const subtitles = [];
let current = "";
for (const sentence of sentences) {
if ((current + sentence).length <= maxChars) {
current += sentence;
} else {
if (current) subtitles.push(current.trim());
current = sentence;
}
}
if (current) subtitles.push(current.trim());
return subtitles;
}
const text = "今日は天気が良い。散歩に出かけよう。公園で、綺麗な花を見つけた。写真を撮った!";
const result = splitForSubtitles(text, 20);
result.forEach((line, i) => {
console.log(`字幕${i + 1}: "${line}" (${line.length}文字)`);
});
実行結果
字幕1: "今日は天気が良い。散歩に出かけよう。" (17文字)
字幕2: "公園で、綺麗な花を見つけた。" (13文字)
字幕3: "写真を撮った!" (7文字)
まとめ
JavaScriptで文字列を句読点ごとに分割する方法を、基本から応用まで解説しました。
| 方法 |
特徴 |
おすすめ度 |
split(/[。、]/) |
基本。シンプルで高速 |
★★★★☆ |
split(/(?<=[。])/) |
区切り文字を残せる。実務向き |
★★★★★ |
matchAll() |
位置情報も取得可能 |
★★★★☆ |
Intl.Segmenter |
言語対応。最も正確 |
★★★★★ |
ポイント:シンプルな句読点分割には split() + 正規表現、区切り文字を残す場合は後読み (?<=...)、多言語対応や高精度な分割が必要な場合は Intl.Segmenter を使いましょう。