排列实战
排列负责打乱,枚举负责挑选。写得好的模板里,真正的多样性来自排列——不是来自堆同义词。本指南讲语法、分隔符规则,以及多数作者错过的那个模式:标题和小标题里的串联列表。
简单排列
[a|b|c]
默认行为:
- 所有元素都包含;
- 每次渲染都打乱顺序;
- 分隔符是一个空格。
输出示例:a b c、c a b、b c a。
单分隔符简写
一笔设置分隔符(连同 lastsep):
[< and >a|b|c]
可能输出:a and b and c、c and a and b。简写把同一字符串同时赋给 sep 和 lastsep,所有连接处长得一样。
完整配置
完整形式给出全部控制:
[<minsize=2;maxsize=4;sep=", ";lastsep=" and ">a|b|c|d|e]
规则:
minsize——最少输出多少个元素;maxsize——最多输出多少个元素;sep——连接除最后一对以外的所有元素;lastsep——连接最后两个元素(自然的 “A, B and C” 输出)。
省略任何一个 size,另一个会合理补位:
- 只设
minsize→maxsize变成“全部可用”; - 只设
maxsize→minsize变成 1; - 两个都大于元素数 → 收敛到总数;
- 引擎不能取零个。“也许根本没有列表”要用空分支包裹(见下)。
单元素分隔符
需要比全局 sep/lastsep 更细的控制时,单个元素可以携带自己的分隔符:
[<, >Visa|Mastercard < and >|Skrill]
这里:
- 全局分隔符是
", "; Mastercard之后的元素带自己的局部分隔符" and "。
单元素分隔符不常用,但某个槽位需要不同连接词时很有用。
分隔符自动补空格
纯单词分隔符两侧会自动补空格:
[<and>a|b|c]
行为等同:
a and b and c
标点分隔符不自动补:
[<,>a|b|c]
产出:
a,b,c
想要逗号后有空格,就显式写上:[<, >a|b|c]。
可选列表
排列不能输出零个元素,所以让列表“也许缺席”的办法是把整个排列包进枚举的空分支:
{|[<minsize=2;maxsize=3;sep=", ";lastsep=" and ">Postgres|Redis|Kafka|MongoDB]}
可能输出:Postgres and Redis、Kafka, Postgres and Redis,或空字符串。记得处理周围的空白——列表可能消失时,把空格留在分支内部。
标题、描述和小标题里的串联列表
这是多数作者错过的模式。标题和 H2/H3 小标题常常许诺几个并列的主题:
Benefits, Integrations, and How to Get Started
这不是一个冻结的字符串——这是三个并列标题块组成的列表。认出这个模式,用排列来写它:
[<minsize=3;maxsize=3;sep=", ";lastsep=", and ">Benefits|Integrations|How to Get Started]
放进带品牌槽位的标题框架里很好用:
%product_name%: [<minsize=3;maxsize=3;sep=", ";lastsep=", and ">Benefits|Integrations|How to Get Started]
不好的写法:
%product_name%: {Benefits, Integrations, and How to Get Started|A Complete Guide for Teams}
第二种形式弱在哪里:
- 把有结构的列表当成一个冻结字符串;
- 丢掉了引擎本来就支持的分隔符模式;
- 把模型推向整串替换,而不是可复用的结构;
- 只产出寥寥几个变体,排列本可以产出几十个。
串联列表模式适用于:
- 列举三个以上卖点的标题;
- 点名几个文章板块的 meta 描述;
- 罗列并列主题的 H1/H2/H3。
顺序是流程性的、必须保持时,不要用它:
Create an account, verify email, and make a deposit
这是步骤序列,不是可以随意打乱的标题列表。
标题的大小写要手动
正文的常规规则说排列元素应以小写开头,因为后处理会把句首大写。
这条规则不适用于标题式的串联列表。每个元素必须直接写成展示时的大小写:
[<minsize=3;maxsize=3;sep=", ";lastsep=", and ">Benefits|Integrations|How to Get Started]
而不是:
[<minsize=3;maxsize=3;sep=", ";lastsep=", and ">benefits|integrations|how to get started]
后处理不会替你把逗号分隔的标题列表转成 Title Case。
排列的常见错误
| 别这样 | 为什么 | 改成这样 |
|---|---|---|
| 硬编码一个 4+ 项的固定列表 | 固定顺序在所有渲染里都是同一个足迹。 | 用排列——集合必选时用 minsize=maxsize 也行。 |
| 把串联标题冻成一个字符串 | 丢掉分隔符模式;变体空间急剧缩水。 | 用带 sep 和 lastsep 的排列输出。 |
用 minsize=0 | 引擎最少收敛到 1;你的期待悄悄落空。 | “也许根本没有列表”用 {|[...]} 包。 |
sep=". " 时还让元素以句号结尾 | 双重标点:"fact. . next fact"。 | 标点交给分隔符;元素保持裸露。 |
| 给引擎已自动补空格的单词分隔符再加空格逻辑 | 为不存在的问题修出 aandb。 | 单词分隔符信任自动补空格;只给标点分隔符手动加。 |
| 排列元素大小写混杂 | 渲染文本的大小写看着像乱码。 | 正文小写,标题 Title Case,一个排列内保持一致。 |
| 让每个元素都是带自己主语的完整句 | 串联的流断掉——每个元素读起来都像新段落。 | 元素保持短语级;主语绑在排列之外。 |
排列检查清单
- 每个 3+ 项列表都是排列,不是冻结字符串。
- 标题里的串联列表用显式
sep/lastsep的排列。 - 可选列表用
{|[...]}包裹,不用minsize=0硬试。 - 排列元素不以分隔符已提供的标点结尾。
- 标题排列直接写展示大小写。
- 正文排列以小写开头,让后处理去大写句首。
- 同一排列里的每个元素都与其他元素语法并列。
结构就位后,最后一道是语法:语法安全的同义替换。