#!/usr/bin/env python3 """词库自检:JSON 合法 / 正则能编译 / 占位符与命名组一一对应 / 候选条数。 用法:python3 validate_phrases.py [phrases.json] 每次改完词库都跑一遍——占位符写错(候选用 {n} 而正则组叫 code)不会报错, 只会在运行时把 {n} 字面量发给用户,肉眼很难发现。 """ import json, re, sys, pathlib path = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else "phrases.json") data = json.loads(path.read_text(encoding="utf-8")) cats = data.get("categories", []) problems, total, minv = [], 0, 10 ** 9 for c in cats: cid = c.get("id", "?") groups = set() for pat in c.get("patterns", []): try: groups |= set(re.compile(pat, re.IGNORECASE).groupindex) except re.error as exc: problems.append(f"{cid}: 正则编译失败 {pat!r} -> {exc}") variants = c.get("variants") or [] total += len(variants) minv = min(minv, len(variants)) for v in variants: missing = set(re.findall(r"\{(\w+)\}", v)) - groups if missing: problems.append(f"{cid}: 候选用了 {sorted(missing)},正则里没有这些组({sorted(groups)})") if not c.get("patterns"): problems.append(f"{cid}: 没有 patterns") if not variants: problems.append(f"{cid}: 没有 variants") print(f"类别 {len(cats)} | 候选 {total} | 最少的一类 {minv} 条") if problems: print(f"\n✗ 发现 {len(problems)} 个问题:") for p in problems: print(" -", p) sys.exit(1) print("✓ 全部通过")