什么是对齐?
对齐是确认哪部分译文对应哪部分原文,可以按整篇、整段或句子建立对应关系。
先读意思,再确认对应
例如,“Close the valve.”应与“关闭阀门。”配对;若配成“检查油量。”,即使两句都通顺,也不能作为同一句的翻译参考。
怎样核对对应关系
整篇文章 ↔ 整篇译文
例如,同一份采购合同的英文版和中文版可以先建立文档对应。标题、编号和日期有助于查找,但还要核对是否为同一版本、是否有删节。
第 N 段英文 ↔ 第 N 段中文
本例页面的段落按“英、中、英、中”交替排列,可先按相邻位置形成候选段落对。这称为结构对齐:利用页面顺序帮助配对;页面夹入广告或缺段时,顺序就可能失效。
一句或相邻几句原文 ↔ 对应译文
分句只是在标点等位置切开文字;对齐还要确认意思对应。例如,英文两句可能合译成一句中文。下方代码只生成顺序相同的候选,不能自动解决这类情况。
对齐的难题
译文可以重组句子,序号相同并不证明对应。检查时先看信息是否完整,再看是否需要合并或拆分候选记录。
错位 (Misalignment)
例如,“Payment is due within 30 days.”误配到“货物应于周五送达。”,这是错位。两边都非空、长度也可能接近,程序未必能发现。
EN ¶3 ↔ ZH ¶4 ✗
拆句或合句(一对多/多对一)
例如,“Payment is due within 30 days, and late payment incurs interest.”译为“款项应在30日内支付。逾期须付利息。”这是一句译两句,可能完全正确,不应直接当成漏译。
1 EN → 2 ZH
干扰内容 (Noise)
例如,系统把“Subscribe now”当成原文,与“关闭阀门。”配在一起。应回查正文提取范围;页码等残留需核对后处理。
<p>...</p> [2]
段落配对 → 句子对齐
requests获取页面,BeautifulSoup提取段落,re分句,zip()按顺序配对。输出是候选句对;数量相同不代表意思对应。
re和zip分别负责什么
re.split()按标点模式分句;zip()只把两个列表中同序号的内容放在一起,不判断意思。缩写“Mr.”也可能被误当作句尾。
候选句对怎样成为可供参考的记录
原文“Close the valve. Check the pressure.”和译文“关闭阀门。检查压力。”可分成两组核对。若中文只有“关闭阀门。”,应回查缺少的信息,不能为了配平数量丢掉第二句英文。
Python代码
import re
import requests
from bs4 import BeautifulSoup
# ① 获取页面
url = "https://cn.nytimes.com/china/20260916/china-english-language-education/dual/"
html = requests.get(url, headers={"User-Agent": "CorpusBot/1.0"}, timeout=30).text
# ② 提取交替排列的双语段落
paragraphs = BeautifulSoup(html, "html.parser").select("div.article-paragraph")
# 假设文本已清洗完毕,此处提取文字
if not paragraphs or len(paragraphs) % 2 != 0:
raise ValueError('正文段落数量异常,需回查页面与选择器')
pairs = []
for i in range(0, len(paragraphs), 2):
en_para = paragraphs[i].get_text().strip()
zh_para = paragraphs[i + 1].get_text().strip()
# ③ 段落内分句
en_sents = [s.strip() for s in re.split(r'(?<=[.!?])\s+', en_para) if s.strip()]
zh_sents = [s.strip() for s in re.split(r'(?<=[。!?])\s*', zh_para) if s.strip()]
if not en_sents or not zh_sents or len(en_sents) != len(zh_sents):
raise ValueError(f'第 {i // 2 + 1} 组句数异常,停止并回查原段')
# ④ 数量核对后形成同序号候选;语义仍须复核
for en, zh in zip(en_sents, zh_sents):
if en.strip() and zh.strip():
pairs.append({
"sentence_english": en.strip(),
"sentence_chinese": zh.strip()
})
print(f"生成 {len(pairs)} 个候选句对,仍需复核")
# pairs 可直接写入 JSON 的 content 字段结构对齐的关键
range(0, len(paragraphs), 2) 利用 NYT 页面「英、中、英、中」的 DOM 规律,
以步长 2 遍历,将相邻两个 div 视为一对。
zip() 的局限
当英中句数不等时,zip() 会静默截断多余句子——
因此本例在配对前核对句数。不等长时停止并回查原段;不能期待事后空值检查找回已丢失的句子。
案例:NYT 双语页对齐流程
此类双语页的英中段落交替排列,可按相邻位置形成候选段落对。段落内仍需分句、核对对应关系并检查内容。
flowchart TD
A["requests 下载 HTML"] --> B["BeautifulSoup 提取 div.article-paragraph"]
B --> C["步长 2 配对英中段落"]
C --> D["re.split 段落内分句"]
D --> E["zip 生成候选"]
E --> F["核对原译文,再保存记录"]
笔译练习:一句译两句是否完整
用途:为设备测试说明寻找保留完整操作要求的译例;原文door指舱门。
原文:Keep the door closed until the test is complete.
译文:请保持舱门关闭。测试完成后方可开启。
系统提示:“原文1句,译文2句,数量不同。”
请判断:这组译文是否保留原文要求?能否仅凭句数不同认定有错?
参考答案
两句中文共同保留了“测试完成前保持舱门关闭”的要求,可以作为一组候选译例。句数不同本身不是错误;若据此判错,就属于误报。不能为凑相同句数删掉其中一句中文。