Sentence Segmentation › Handling Edge Cases
Language AI HandbookAll chapters Sentence Segmentation › Handling Edge CasesOne section · Sections in this chapter5 / 14 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Real-world text contains numerous edge cases that challenge even sophisticated segmenters. Most NLP tutorials present clean, well-formed text where the right answer is obvious. Production systems face something very different: user-generated content with informal grammar, technical documents with non-standard punctuation, legal transcripts with interrupted speech, and web-scraped text littered with encoding artifacts. Understanding the common failure modes helps you anticipate where your segmenter will struggle and design appropriate postprocessing strategies.
The four categories of edge cases that follow represent the most commonly encountered problems. Each one exploits a different weakness in the assumptions that most segmenters make. Quotation marks embed one sentence's punctuation inside another sentence's scope. Numbered lists use periods in structural roles rather than sentence-ending roles. Ellipses represent intentionally unresolved sentence boundaries. Multiple punctuation marks stack signals that segmenters must interpret coherently. A production-quality segmenter needs explicit strategies for all four.
Quotations and Parentheses
Sentences can contain quoted speech or parenthetical remarks that include their own sentence-ending punctuation. This creates a structural nesting problem: the outer sentence has not ended, but the inner quoted material has its own punctuation that a simple scanner would interpret as a sentence boundary. The challenge is especially acute in American typographic convention, where periods and question marks go inside closing quotation marks regardless of whether they end the outer sentence. British convention places them outside, but American convention places them inside, so the same surface string has different structural interpretations depending on the typographic tradition.
# Edge cases with quotes and parentheses
edge_cases = [
'He said, "Hello." She waved back.',
'"Hello," he said. "How are you?"',
"The book (published in 2020) was popular. It sold millions.",
'She shouted, "Stop!" He kept running.',
"(See Appendix A.) The data supports this claim.",
]
edge_results = [(text, sent_tokenize(text)) for text in edge_cases]Quotation and Parenthesis Edge Cases: ====================================================================== Input: "He said, "Hello." She waved back." 1. "He said, "Hello."" 2. "She waved back." Input: ""Hello," he said. "How are you?"" 1. ""Hello," he said." 2. ""How are you?"" Input: "The book (published in 2020) was popular. It sold millions." 1. "The book (published in 2020) was popular." 2. "It sold millions." Input: "She shouted, "Stop!" He kept running." 1. "She shouted, "Stop!"" 2. "He kept running." Input: "(See Appendix A.) The data supports this claim." 1. "(See Appendix A.)" 2. "The data supports this claim."
Lists and Enumerations
Numbered or bulleted lists present unique challenges because they use periods in a structural role that is entirely different from sentence-ending. The period after "1." in "1. Prepare the data." marks a list item, not a sentence boundary in the traditional sense. Whether this should be treated as a sentence boundary depends on the downstream task. For text-to-speech, each list item should probably be read as a separate prosodic unit. For machine translation, the items might need to be translated individually. For summarization, each item might be a candidate for inclusion. The "right" answer depends on application semantics, not on linguistic convention.
# List-style text
list_text = """
The process has three steps:
1. Prepare the data.
2. Train the model.
3. Evaluate results.
Each step is critical for success.
"""
list_sentences = sent_tokenize(list_text.strip())List Segmentation: -------------------------------------------------- Input text: The process has three steps: 1. Prepare the data. 2. Train the model. 3. Evaluate results. Each step is critical for success. Sentences found: 1. "The process has three steps: 1." 2. "Prepare the data." 3. "2." 4. "Train the model." 5. "3." 6. "Evaluate results." 7. "Each step is critical for success."
Ellipses
Ellipses (...) can appear mid-sentence or at sentence boundaries and represent a different kind of ambiguity from abbreviations. An abbreviation period has a determinate answer: either the word is an abbreviation or it is not, and the period either ends the sentence or does not. An ellipsis is intentionally indeterminate: it signals a pause, a trailing thought, or an omission, and whether it constitutes a sentence boundary depends on the writer's intent. In transcribed speech or informal writing, ellipses are especially common and especially ambiguous. A segmenter that always splits on ellipses will over-segment; one that never splits on them will merge sentences that should be separate.
# Ellipsis examples
ellipsis_texts = [
"Wait... I think I understand now.",
"She paused... then continued speaking.",
"The answer is... well, complicated.",
"He said he would come... He never did.",
]
ellipsis_results = [(text, sent_tokenize(text)) for text in ellipsis_texts]Ellipsis Handling: ============================================================ Input: "Wait... I think I understand now." 1. "Wait..." 2. "I think I understand now." Input: "She paused... then continued speaking." 1. "She paused... then continued speaking." Input: "The answer is... well, complicated." 1. "The answer is... well, complicated." Input: "He said he would come... He never did." 1. "He said he would come..." 2. "He never did."
Multiple Punctuation
Some sentences end with multiple punctuation marks:
# Multiple punctuation
multi_punct = [
"Really?! I can't believe it!",
"What...? That makes no sense.",
'She asked, "Are you sure?!" He nodded.',
"Wait!! Stop!! Don't do that!!",
]
multi_results = [(text, sent_tokenize(text)) for text in multi_punct]Multiple Punctuation Marks: ============================================================ Input: "Really?! I can't believe it!" 1. "Really?!" 2. "I can't believe it!" Input: "What...? That makes no sense." 1. "What...?" 2. "That makes no sense." Input: "She asked, "Are you sure?!" He nodded." 1. "She asked, "Are you sure?!"" 2. "He nodded." Input: "Wait!! Stop!! Don't do that!!" 1. "Wait!!" 2. "Stop!!" 3. "Don't do that!" 4. "!"