算法

Unicode 换行算法

根据字符属性、CJK词边界和换行时机,确定文本可换至下一行位置的规则。

· Updated

Breaking Text Across Lines

When a paragraph of text is too wide for its container, a rendering engine must decide where to insert line breaks. This sounds straightforward but involves subtle rules that vary by script, language, and context. The Unicode Line Breaking Algorithm (UAX #14) provides a systematic framework for finding valid break opportunities.

The algorithm does not tell renderers where to break — that depends on line width and font metrics. Instead, it classifies each position between characters as a mandatory break, a break opportunity (the renderer may break here), or no break (breaking here is not allowed).

Line Break Classes

Each Unicode character is assigned a line break class. There are over 40 classes; the most important:

Class Code Examples Behavior
Break After BA spaces, hyphens Break opportunity after
Break Before BB em dash in some contexts Break opportunity before
Alphabetic AL Latin, Cyrillic letters No break between letters
Ideographic ID CJK unified ideographs Break opportunity after each
Nonstarter NS Japanese small kana (っ, ょ) Cannot start a new line
Close Punctuation CL ), ], » No break before (attaches to preceding)
Open Punctuation OP (, [, « No break after (attaches to following)
Mandatory Break BK U+000C FORM FEED Must break here
Carriage Return CR U+000D Mandatory break (with LF handling)
Glue GL U+00A0 NO-BREAK SPACE No break allowed

The key insight for international text: CJK ideographic characters (Chinese, Japanese, Korean) have a break opportunity after almost every character because those scripts historically had no spaces. Latin letters have no break opportunities between them — only at space or hyphen positions.

Connection to CSS

The UAX #14 algorithm is the foundation for CSS line-breaking properties:

/* Allow break at any character (overrides UAX #14 for CJK) */
word-break: break-all;

/* Break long words that would overflow */
overflow-wrap: break-word;

/* Strict CJK line breaking (no breaks before small kana) */
line-break: strict;

/* Loose CJK line breaking (more break opportunities) */
line-break: loose;

/* Prevent breaking across lines entirely */
white-space: nowrap;

Python and Line Breaking

Python's textwrap module uses a simplified version of line breaking for ASCII-centric text. For full UAX #14 compliance, the uharfbuzz or PyICU libraries provide proper implementations:

import textwrap

# Basic wrapping (works for Latin text)
text = "The quick brown fox jumps over the lazy dog."
print(textwrap.fill(text, width=30))

# For CJK text, textwrap.fill does NOT insert breaks
# between ideographs — use a proper UAX #14 implementation
# (uharfbuzz, or browser rendering)

Quick Facts

Property Value
Specification Unicode Standard Annex #14 (UAX #14)
Number of line break classes 43
CJK default Break opportunity after every ideograph
Latin default No break except at spaces/hyphens
CSS connection word-break, overflow-wrap, line-break
Mandatory break chars U+000A LF, U+000D CR, U+000C FF, U+0085 NEL, U+2028 LS, U+2029 PS
No-break space U+00A0 has class GL (Glue) — prevents break at that position

相关术语

算法 中的更多内容

Case Folding

Mapping characters to a common case form for case-insensitive comparison. More comprehensive …

Grapheme Cluster Boundary

Rules (UAX#29) for determining where one user-perceived character ends and another begins. …

NFC (Canonical Composition)

规范化形式C:先分解再规范合成,生成最短形式,推荐用于数据存储和交换,是Web标准形式。

NFD (Canonical Decomposition)

规范化形式D:完全分解而不重新合成,macOS HFS+文件系统使用此形式。é(U+00E9)→ e + ◌́(U+0065 + U+0301)。

NFKC (Compatibility Composition)

规范化形式KC:兼容分解后再规范合成,合并视觉上相似的字符(fi→fi、²→2、Ⅳ→IV),用于标识符比较。

NFKD (Compatibility Decomposition)

规范化形式KD:兼容分解而不重新合成,是最激进的规范化方式,会丢失最多的格式信息。

String Comparison

Comparing Unicode strings requires normalization (NFC/NFD) and optionally collation (locale-aware sorting). Binary …

Unicode 双向算法 (UBA)

利用字符双向类别和明确方向覆盖,确定混合方向文本(如英语+阿拉伯语)显示顺序的算法。

Unicode 排序算法 (UCA)

通过多级比较(基础字符→变音符号→大小写→决胜符)对Unicode字符串进行比较和排序的标准算法,支持区域设置自定义。

Unicode 文本分割

查找文本中各类边界的算法:字素簇、词和句子边界,对光标移动、文本选择和文本处理至关重要。