diff --git a/parser.py b/parser.py index 441fce6..12513d6 100644 --- a/parser.py +++ b/parser.py @@ -316,10 +316,20 @@ _year_digits = '〇零一二三四五六七八九十廿卄卅卌' + '0123456789 _known_era_alt = '|'.join(sorted(KNOWN_ERAS_ALL, key=len, reverse=True)) _known_era_group = r'(?P' + _known_era_alt + r')' _yd = '[' + _year_digits + ']' -# 年份后缀:"年"字可省,但只在紧跟合法干支时才成立——碑谱/契约常见写法 -# ("光绪二十六庚子" = 光绪二十六年庚子,"民国二十五丙子" = 民国二十五年丙子)。 -# 干支是判定依据:省"年"的年份后面必然跟干支,否则不认(防止"康熙二十"这类普通数字误匹配)。 -_year_suffix = r'(?:年|(?=' + _gz_pair + r'))' +# 年份后缀:"年"字可省(碑谱/契约常见:"民国二十六""万历三十六",也支持后接干支 +# "光绪二十六庚子")。省"年"时靠负向前瞻 _year_guard 兜住误匹配: +# 数字后面若还是数字字符或 万/亿,说明它只是一个更长数量的一部分("万历二十万"),不认。 +# 该 guard 同时挡住正则回溯:若整体匹配失败而回退到更短的数字串,其下一个字符必然仍是 +# 数字字符,guard 同样不通过(Python 3.10 没有原子组/占有量词,只能这样写)。 +# 裸年份(后面既无"年"、也无干支)后面若跟这些字,说明数字不是年数,一律不认: +# 月/日/号 → 月份日期("康熙六月""民国七月十二") +# 子/女/弟/兄/孙/婿/郎 → 亲属排行("张景福三子") +# 都/图/里 → 地名/行政区("永明五十二都") +# 岁/人/名/位/个/两/斤/石/亩/间/匹/只/件/张/条/次/层/种/倍/余/多 → 量词/约数 +# 注意不含天干(甲乙丙丁…):紧跟干支的写法("光绪二十六庚子")不受影响。 +_bare_year_forbid = '月日号子女子弟兄孙婿郎都图里岁人名位个两次条张匹只件斤两石亩间层种倍余多' +_year_guard = r'(?![' + _year_digits + r'万亿' + _bare_year_forbid + r'])' +_year_suffix = _year_guard + r'(?:年)?' def _build_pattern(with_dynasty=True): """构建年号正则:已知年号优先 + 通用兜底(仅限有朝代前缀时)"""