This commit is contained in:
131
internal/shared/pdf/text_processor.go
Normal file
131
internal/shared/pdf/text_processor.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package pdf
|
||||
|
||||
import (
|
||||
"html"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TextProcessor 文本处理器
|
||||
type TextProcessor struct{}
|
||||
|
||||
// NewTextProcessor 创建文本处理器
|
||||
func NewTextProcessor() *TextProcessor {
|
||||
return &TextProcessor{}
|
||||
}
|
||||
|
||||
// CleanText 清理文本中的无效字符和乱码
|
||||
func (tp *TextProcessor) CleanText(text string) string {
|
||||
// 先解码HTML实体
|
||||
text = html.UnescapeString(text)
|
||||
|
||||
// 移除或替换无效的UTF-8字符
|
||||
var result strings.Builder
|
||||
for _, r := range text {
|
||||
// 保留:中文字符、英文字母、数字、常见标点符号、空格、换行符等
|
||||
if (r >= 0x4E00 && r <= 0x9FFF) || // 中文字符范围
|
||||
(r >= 0x3400 && r <= 0x4DBF) || // 扩展A
|
||||
(r >= 0x20000 && r <= 0x2A6DF) || // 扩展B
|
||||
(r >= 'A' && r <= 'Z') || // 大写字母
|
||||
(r >= 'a' && r <= 'z') || // 小写字母
|
||||
(r >= '0' && r <= '9') || // 数字
|
||||
(r >= 0x0020 && r <= 0x007E) || // ASCII可打印字符
|
||||
(r == '\n' || r == '\r' || r == '\t') || // 换行和制表符
|
||||
(r >= 0x3000 && r <= 0x303F) || // CJK符号和标点
|
||||
(r >= 0xFF00 && r <= 0xFFEF) { // 全角字符
|
||||
result.WriteRune(r)
|
||||
} else if r > 0x007F && r < 0x00A0 {
|
||||
// 无效的控制字符,替换为空格
|
||||
result.WriteRune(' ')
|
||||
}
|
||||
// 其他字符(如乱码)直接跳过
|
||||
}
|
||||
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// CleanTextPreservingMarkdown 清理文本但保留markdown语法字符
|
||||
func (tp *TextProcessor) CleanTextPreservingMarkdown(text string) string {
|
||||
// 先解码HTML实体
|
||||
text = html.UnescapeString(text)
|
||||
|
||||
// 移除或替换无效的UTF-8字符,但保留markdown语法字符
|
||||
var result strings.Builder
|
||||
for _, r := range text {
|
||||
// 保留:中文字符、英文字母、数字、常见标点符号、空格、换行符等
|
||||
// 特别保留markdown语法字符:* _ ` [ ] ( ) # - | : !
|
||||
if (r >= 0x4E00 && r <= 0x9FFF) || // 中文字符范围
|
||||
(r >= 0x3400 && r <= 0x4DBF) || // 扩展A
|
||||
(r >= 0x20000 && r <= 0x2A6DF) || // 扩展B
|
||||
(r >= 'A' && r <= 'Z') || // 大写字母
|
||||
(r >= 'a' && r <= 'z') || // 小写字母
|
||||
(r >= '0' && r <= '9') || // 数字
|
||||
(r >= 0x0020 && r <= 0x007E) || // ASCII可打印字符(包括markdown语法字符)
|
||||
(r == '\n' || r == '\r' || r == '\t') || // 换行和制表符
|
||||
(r >= 0x3000 && r <= 0x303F) || // CJK符号和标点
|
||||
(r >= 0xFF00 && r <= 0xFFEF) { // 全角字符
|
||||
result.WriteRune(r)
|
||||
} else if r > 0x007F && r < 0x00A0 {
|
||||
// 无效的控制字符,替换为空格
|
||||
result.WriteRune(' ')
|
||||
}
|
||||
// 其他字符(如乱码)直接跳过
|
||||
}
|
||||
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// StripHTML 去除HTML标签(不转换换行,直接移除标签)
|
||||
func (tp *TextProcessor) StripHTML(text string) string {
|
||||
// 解码HTML实体
|
||||
text = html.UnescapeString(text)
|
||||
|
||||
// 直接移除所有HTML标签,不进行换行转换
|
||||
re := regexp.MustCompile(`<[^>]+>`)
|
||||
text = re.ReplaceAllString(text, "")
|
||||
|
||||
// 清理多余空白
|
||||
text = strings.TrimSpace(text)
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
// RemoveMarkdownSyntax 移除markdown语法,保留纯文本
|
||||
func (tp *TextProcessor) RemoveMarkdownSyntax(text string) string {
|
||||
// 移除粗体标记 **text** 或 __text__
|
||||
text = regexp.MustCompile(`\*\*([^*]+)\*\*`).ReplaceAllString(text, "$1")
|
||||
text = regexp.MustCompile(`__([^_]+)__`).ReplaceAllString(text, "$1")
|
||||
|
||||
// 移除斜体标记 *text* 或 _text_
|
||||
text = regexp.MustCompile(`\*([^*]+)\*`).ReplaceAllString(text, "$1")
|
||||
text = regexp.MustCompile(`_([^_]+)_`).ReplaceAllString(text, "$1")
|
||||
|
||||
// 移除代码标记 `code`
|
||||
text = regexp.MustCompile("`([^`]+)`").ReplaceAllString(text, "$1")
|
||||
|
||||
// 移除链接标记 [text](url) -> text
|
||||
text = regexp.MustCompile(`\[([^\]]+)\]\([^\)]+\)`).ReplaceAllString(text, "$1")
|
||||
|
||||
// 移除图片标记  -> alt
|
||||
text = regexp.MustCompile(`!\[([^\]]*)\]\([^\)]+\)`).ReplaceAllString(text, "$1")
|
||||
|
||||
// 移除标题标记 # text -> text
|
||||
text = regexp.MustCompile(`^#{1,6}\s+(.+)$`).ReplaceAllString(text, "$1")
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
// RemoveNonASCII 移除非ASCII字符(保留ASCII字符和常见符号)
|
||||
func (tp *TextProcessor) RemoveNonASCII(text string) string {
|
||||
var result strings.Builder
|
||||
for _, r := range text {
|
||||
// 保留ASCII字符(0-127)
|
||||
if r < 128 {
|
||||
result.WriteRune(r)
|
||||
} else {
|
||||
// 中文字符替换为空格或跳过
|
||||
result.WriteRune(' ')
|
||||
}
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
Reference in New Issue
Block a user