《拉鲁斯法汉双解词典》 文本数据(OCR)

校对过程中发现原词典也有少量文字讹误,多处把“脉搏”写成“脉博”,“最后通牒”成了“通谍”,像这里(见P1101)的lamproie,当为“无颌纲,圆口目;最长为1米”,在书中印成了“无颚纲,圆目;最长为1 米”,无论译者还是编辑,稍微有点动物学常识,就会知道它们是错的。

2 个赞

之前的工具已经替换成了正确版本,我其实一直想把这个改成更通用的,比如支持excel还有主流文档格式,包括pdf,docx和txt这些,如果用pandas甚至数据库什么的也能支持。不过都要配置参数才能用,因为txt没有明显分页的,只能指定分页符或者行对齐。

修改了200多处括号问题,现在还有700多处,另外现在还有50多页不能和图片匹配。 我研究下怎么重构下校对工具直接在txt上改可能有错的地方。

2 个赞

(帖子已被作者删除)

词典中的音标有很多错误,因此抓取、提取了拉鲁斯官网和1995法文版拉鲁斯词典的音标数据,对它们进行了批量替换。

拉鲁斯官网的数据质量实际也不咋样,比如εɛ,œɶ不区分,ʀ写成r,还有少量彻底的错乱,我初步做了检查和清洗。

下面是替换音标使用的script:

def load_pronunciation(file):
    """
    从文件中加载单词到音标的映射
    """
    mapping = {}
    with open(file, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if not line or " [" not in line:
                continue
            
            # 使用 " [" 进行分割
            parts = line.split(" [", maxsplit=1)
            
            if len(parts) == 2:
                word = parts[0]
                phon_part = parts[1]

                # 查找第一个闭合方括号的位置
                end_bracket_pos = phon_part.find(']')
                if end_bracket_pos == -1:
                    continue # 如果没有找到 ']',说明格式有问题,跳过此行

                # 只截取到第一个 ']' 之前的内容作为音标
                phon = phon_part[:end_bracket_pos]
                
                mapping[word.rstrip(",")] = phon
    return mapping

# --- 程序开始 ---

# 1. 初始化计数器
count_from_2 = 0
count_from_3 = 0

# 加载音标库
print("正在加载音标库...")

phon2 = load_pronunciation("2.txt")
phon3 = load_pronunciation("3.txt")
print("音标库加载完成。")

# 处理主文件,并同时打开日志文件
print("正在处理文件 1.txt...")
with open("1.txt", "r", encoding="utf-8") as f, \
     open("1_fixed_04.txt", "w", encoding="utf-8") as out, \
     open("replacement_log.txt", "w", encoding="utf-8") as log_file:

    # 写入日志文件标题
    log_file.write("音标替换日志\n")
    log_file.write("="*30 + "\n")

    for line in f:
        # 在主处理逻辑中,只处理正文部分,简单通过特征判断
        # 这里假设词条行总是以字母开头,且包含 "[音标]" 格式
        head = line[:45]  # 截取每行文字的前45个字符,以防误改
        
        if head.strip() and " [" in head:
            parts = head.split(" [", maxsplit=1)
            if len(parts) == 2:
                word = parts[0]
                old_phon_part = parts[1]
                
                end_bracket_pos = old_phon_part.find(']')
                if end_bracket_pos != -1:
                    old_phon = old_phon_part[:end_bracket_pos]

                    # 查找新音标
                    new_phon = old_phon
                    source_file = None

                    # 优先从 phon2 查找,如果找不到再查 phon3;排除2当中某些不合体例的音标
                    if word in phon2 and phon2[word] != old_phon and ',' not in phon2[word] and not '(' in phon2[word]:
                        new_phon = phon2[word]
                        source_file = "2.txt"
                        count_from_2 += 1
                    elif word in phon3 and phon3[word] != old_phon:
                        new_phon = phon3[word]
                        source_file = "3.txt"
                        count_from_3 += 1
                    
                    # 只有当音标确实有差别时,才进行替换和记录
                    if source_file:
                        log_entry = f"{word}: [{old_phon}] → [{new_phon}]〈{source_file}〉\n"
                        log_file.write(log_entry)

                        old_phon_with_brackets = f"[{old_phon}]"
                        new_phon_with_brackets = f"[{new_phon}]"
                        
                        fixed_head = head.replace(old_phon_with_brackets, new_phon_with_brackets, 1)
                        line = fixed_head + line[len(head):]

        out.write(line)

# --- 打印最终统计结果 ---
total_replacements = count_from_2 + count_from_3
print("\n--- 处理完成 ---")
print(f"总共替换了 {total_replacements} 个音标。")
print(f"  - 从 2.txt 替换: {count_from_2} 个")
print(f"  - 从 3.txt 替换: {count_from_3} 个")
print("修改后的文件已保存为 1_fixed.txt。")
print("替换记录已保存到 replacement_log.txt 文件中。")

这里1.txt是原始文件,2是拉鲁斯官网抓取的音标(做过一些修正和删除清洗),3为从法文版拉鲁斯词典里提取的音标。虽然最后的结果未必全部正确,可以大大减少音标部分内容人工校正的工作量。

输出结果为:

总共替换了 22793 个音标。
- 从 2.txt 替换: 16525 个
- 从 3.txt 替换: 6268 个

2 个赞

在处理音标的同时,使用不同OCR来源文本对校的办法,从头到尾核查校订了词典的中文文本,不能夸口说这样就消灭了错误,但可以把错误率控制在较低的水平。

法文文本部分可以对校,也可以使用拼写检查工具,或者用ai来处理,实验之后再确定哪种办法比较便捷理想。

中法文的标点是比较难处理的,图像模糊,原书标点经常人眼都看不清,我发现某些译者在该使用什么标点时本身也是糊涂的,本词典的体例应该是中文译文短语不加标点,完整的句子则加句号,但好像有部分页面则完全不遵守,短语也加上了句号。

1995年版法文拉鲁斯词典(仅正文部分),Gemini 2.5 Pro 识别、OCR。

dictionnaire de la langue française.txt (8.3 MB)

1 个赞

整了一个初步的简易语法,是基于python的语法分析库lark的。可以用来查错(不过前提是语法能覆盖所有情况,还需要再完善),也可以直接解析出结构便于加标签。
可以用在线IDE测试:

随机选了一页测试(238页),这里有报错,说明格式不对,这就查出来这里◆应该替换为❹


改正后会有解析结果

这是所用的语法,基本就是EBNF

9-14最新版本的语法文件
larousse_grammar.txt (2.6 KB)

3 个赞

校对工具大更新,现在支持直接读取txt文件了,也能保存txt文件。然后括号匹配问题可以直接给出修正(如果缺括号暂时还不能修正),然后因为格式更改现在图片加载功能还有问题。

还是在这个分支:

辛苦了,我试试。

刚好我也搞了一个简略的文本对比工具,它是整页文字比较的,pdf图像作为稽核参考,相对容易实现。

1 个赞

这个不错,很简洁,整页对比也不用处理切分对齐问题了,是用python自带gui库Tkinter的吧。

对,是tkinter实现的UI,你用的nicegui我还没用过,不熟悉。它也实现了初步的过滤功能,可以用正则忽略某些自己还不想比较的字符。

在单词层级比较的一大问题是预处理麻烦,有些单词错误合并在一起,有些一个单词分成了两项。在拉鲁斯法汉双解词典里,我发现还有连续若干单词被原纸本书遗漏了的情况。在页面层级比较,就没这么多烦心事了,不过它可能更适合单页文字少字体大的状况,一个页面里一眼全能看清楚。

nicegui是基于网页那套的,优点是样式什么的比较容易调整,缺点是底层实现比较复杂,而且受浏览器限制。字符过滤我其实写了一个,是用SequenceMatcher的结果后处理的,效果一般,不知道你是怎么实现的。 我觉得要文本化肯定最终要到单词层面处理的,不过单词层面就不适合直接比较txt文件了,各种跨页问题很容易在保存时出错,拉鲁斯里面faire这个词跨了3页。

用新工具校对了一下发现原书错误真不少。
现在支持正则替换作为规则了,写了个严格验证缩略词的规则,发现不少问题

原文就有好多地方都不一致,神话好几个地方标注的〔神化〕

还有1354页第2条有22个释义,但是黑圆圈21以后没有unicode编码了,所以先用普通圆圈代替了。

现在括号匹配错误还有500多处

1 个赞

双解版、法文版的原书都有错误,比如只有一个释义项也使用❶ / -1.符号,无错不成书,文字量太大,几百万,偶尔出现这种编校失误在所难免。

目前词条对比完成:
当前双解版词条数34777
法文版词条数34779

法文版和双解版都有问题
法文版缺以下词条

  1. bille
  2. blanc

中文版缺以下词条
vacillement
vaciller
vacuité
vacuole

此外法文版和中文版这两个词条fourrager和mien都有两个释义,但是没有加编号区分。

2 个赞

中文版词典自身遗漏缺失词条,我在以前就发现了,贴在 github 的issue里, 我想可以先把它在双解版里补上,对应的中文翻译后面手工添加。 词典原书错误举例 · Issue #6 · mahavivo/larousse · GitHub

校对工具大更新,支持候选文本用不同的key查找,支持过滤字符比较,可以对比中文和法文,应用变化和替换文本分开。上方可以自定义各种字段跳转(比如拉鲁斯可以跳转到指定页page,指定页指定条目id,指定条目_index和指定单词headword。

3 个赞

相应的切图图片在github上吗?