| 12345678910111213141516171819202122232425262728293031323334353637383940 |
- #!/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("✓ 全部通过")
|