fix(term): 清理百度百科摘要的截断结尾
百度百科 BaikeLemmaCardApi 摘要以 ... 硬截断,出现半截话。 新增 trimTruncatedTail:去掉结尾省略号后,若末句不完整则 回退到最后一个完整句标点(。!?),避免「唐宋时期,冬至...」 这类戛然而止的结尾。仅依赖百度百科,不引入维基,线上可用。
This commit is contained in:
@@ -247,7 +247,7 @@ func (s *BaikeTermSyncService) syncOneTerm(name string) error {
|
|||||||
}
|
}
|
||||||
extraJSON, _ := json.Marshal(extra)
|
extraJSON, _ := json.Marshal(extra)
|
||||||
|
|
||||||
content := cleanTermHTML(lemma.Abstract)
|
content := trimTruncatedTail(cleanTermHTML(lemma.Abstract))
|
||||||
brief := extra["meaning"]
|
brief := extra["meaning"]
|
||||||
if brief == "" {
|
if brief == "" {
|
||||||
brief = firstSentence(content)
|
brief = firstSentence(content)
|
||||||
@@ -365,3 +365,34 @@ func cleanTermHTML(s string) string {
|
|||||||
s = reTermSpace.ReplaceAllString(s, " ")
|
s = reTermSpace.ReplaceAllString(s, " ")
|
||||||
return strings.TrimSpace(s)
|
return strings.TrimSpace(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trimTruncatedTail 清理百度百科摘要的截断结尾:
|
||||||
|
// 摘要以「...」「…」等结尾说明被接口截断,先去掉省略号;
|
||||||
|
// 若去掉后末句不是完整句(不以 。!? 结尾),回退到最后一个完整句标点,避免半截话
|
||||||
|
func trimTruncatedTail(s string) string {
|
||||||
|
// 去掉结尾的省略号(英文 ... / 中文 … / 多个点)
|
||||||
|
s = strings.TrimRight(s, ".… ")
|
||||||
|
if s == "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
// 末字符已是完整句标点则无需回退
|
||||||
|
last := []rune(s)
|
||||||
|
if len(last) == 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if strings.ContainsRune("。!?", last[len(last)-1]) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
// 回退到最后一个完整句标点(LastIndex 未找到返回 -1,需先判断 j >= 0)
|
||||||
|
idx := -1
|
||||||
|
for _, sep := range []string{"。", "!", "?"} {
|
||||||
|
if j := strings.LastIndex(s, sep); j >= 0 && j+len(sep) > idx {
|
||||||
|
idx = j + len(sep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if idx > 0 {
|
||||||
|
return s[:idx]
|
||||||
|
}
|
||||||
|
// 没有完整句标点则保留原文(避免清空)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|||||||
@@ -128,3 +128,24 @@ func TestTermSort(t *testing.T) {
|
|||||||
t.Errorf("termSort(不存在) = %d, want 0", termSort("不存在"))
|
t.Errorf("termSort(不存在) = %d, want 0", termSort("不存在"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTrimTruncatedTail(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
in string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"完整句号结尾不动", "夏至后人们普遍食用清补凉汤来避暑。", "夏至后人们普遍食用清补凉汤来避暑。"},
|
||||||
|
{"英文省略号回退", "表达感谢的心情。唐宋时期,冬至...", "表达感谢的心情。"},
|
||||||
|
{"中文省略号回退", "表达感谢的心情。唐宋时期,冬至…", "表达感谢的心情。"},
|
||||||
|
{"无句号半截话保留", "可明显感觉到早春的气...", "可明显感觉到早春的气"},
|
||||||
|
{"多点省略号", "农事谚语....", "农事谚语"},
|
||||||
|
{"结尾空白加省略号", "冬至大如年。 ...", "冬至大如年。"},
|
||||||
|
{"空字符串", "", ""},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
if got := trimTruncatedTail(c.in); got != c.want {
|
||||||
|
t.Errorf("%s: trimTruncatedTail(%q) = %q, want %q", c.name, c.in, got, c.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user