构造反例样本的目的,是在批量替换执行之前,主动找出那些“个别样本成立、规模化后翻车”的边界条件。做法不是随机多抽几条,而是从你手上的资料或页面里,按结构差异和上下文差异各挑出一组,先对它们单独跑一遍替换规则,把不成立的挑出来,再决定规则要不要收窄。
假设你手上是一份应用内文案表或一个帮助中心页面集合,里面混着标题、按钮文字、说明段落、报错提示。不要把它们当成同一种文本处理。先按“出现位置”和“句式角色”各分一层:位置决定它有没有长度限制或变量占位符,句式角色决定替换后语义是否还通顺。分完之后你会发现,真正需要批量替换的往往只是其中一两个子集,其余子集本身就不该被同一条规则覆盖。这一步的产出是一张分组清单,而不是马上写替换表达式。分组清单越贴近实际结构,后面构造反例就越省力。
反例样本要覆盖三种容易漏掉的情况,每类不必多,两三条即可,但必须来自真实资料,不能凭印象编。
<版本号>、{用户名} 这类片段。挑出这类样本,检验替换后占位符是否被截断或拼接错位。这三组合起来,就是你的最小反例集。它的价值不在于数量,而在于每条都对应一种“规模化后才会暴露”的失败模式。
拿反例集逐条跑一遍你的替换规则,记录每条是命中、误伤还是漏掉。如果某条反例被误伤,说明规则的范围太宽,需要加上前后文限定;如果某条该替换却没替换,说明限定过严。此时不要急着改规则再全量跑,而是先把“误伤”和“漏掉”分别对应到分组清单里的哪个子集,判断这个子集是否值得单独处理。一个常见结果是:反例逼你放弃一条通吃规则,拆成两三条更窄的规则,分别作用于不同子集。这个取舍本身就是反例样本要换来的东西。
假设待替换词是“设置”,资料里有“打开设置”“设置提醒时间”“默认设置已恢复”。前两条应替换,第三条里“设置”是名词,替换后会读不通。把第三条放进反例集,规则加上“后面不接‘已’‘被’等词”的限定。改完再只对反例集复跑,确认误伤消失,才进入下一步。这里的数字和词都只是说明比较方法,不代表任何真实项目。
复跑反例集通过,不等于全量安全。执行批量替换后,至少要做两件事:一是把反例集所在的子集单独导出,人工看一遍替换结果;二是保留替换前的原文快照,便于逐条对照。如果替换前后正好赶上版本发布或搜索需求波动,页面表现的变化不能直接归因于这次替换,需要把采集时间、样本范围和对照对象写清楚。反例集全部通过、且原文快照可回溯,才是可以继续扩大替换范围的条件;只要还有一条反例状态不明,就先停在这个子集,不要全量推进。