Baris teks yang sama dibagi menjadi lebih dari sepuluh bentang oleh PyMuPDF? Ini menentukan apakah harus digabungkan
PyMuPDF membagi baris kata yang sama menjadi lebih dari selusin rentang. Seringkali, font, ukuran font, atau gayanya berubah, belum tentu segmentasinya. Artikel ini menjelaskan cara membedakan perubahan gaya dan batasan paragraf, serta memberikan contoh penggabungan logika dan bentuk penerimaan untuk menghindari terpotong-potongnya kalimat selama penerjemahan.
Saat Anda menggunakan extractDICT() PyMuPDF untuk mengekstrak teks PDF, Anda mungkin menemukan bahwa kalimat yang koheren dipotong menjadi tujuh, delapan atau lebih span di hasil yang dikembalikan. Ini biasanya bukan kesalahan penguraian, tetapi cerminan sebenarnya dari struktur dasar PDF: peralihan font, perubahan warna, atau penyesuaian gaya lokal dapat mengganggu aliran teks saat rendering.
Jika "pengirisan gaya" ini disalahartikan sebagai "segmentasi paragraf", pembersihan, penerjemahan, atau pengambilan selanjutnya akan dengan mudah menyebabkan kesalahan segmentasi kalimat. Artikel ini menjelaskan cara membedakan perubahan gaya dari batas paragraf, memberikan contoh gabungan logika penggabungan, dan memberikan formulir penerimaan untuk membantu Anda menghindari pemotongan kalimat.
Sebaris teks dalam PDF dibagi menjadi beberapa bentang. Haruskah mereka digabungkan? Kesimpulan satu kalimat
Jika ada beberapa span di line yang sama dan koordinat y sama, sebagian besar adalah font, ukuran font, atau peralihan warna, yang dapat disambung dengan aman; batas paragraf harus berdasarkan struktur block dan line, bukan berdasarkan jumlah span.
| situasi Anda | Praktik yang direkomendasikan | alasan |
|---|---|---|
| Beberapa bentang dalam satu garis mempunyai koordinat y yang sama | Splicing yang aman span.teks | Sebagian besar pergantian font atau warna |
| Ada kesenjangan horizontal yang jelas antar bentang | Periksa spasi bbox dan masukkan spasi atau tab jika perlu | Mungkin sisa karakter tab atau kolom pecah, memerlukan aturan |
| Perbedaan koordinat y bentang dalam baris yang sama melebihi 10% ukuran font | Pertahankan struktur bentang asli tanpa penggabungan | Mungkin berupa rumus sebaris atau subskrip |
| Rentang kata tunggal dan bbox tidak berurutan | Tandai sebagai kualitas rendah, ubah ke manual atau OCR | Kurangnya dasar yang dapat diandalkan untuk menyortir dan mengelompokkan |
| Teks yang berkesinambungan secara semantik melintasi blok | Penilaian kontekstual diperlukan dan penggabungan otomatis tidak dilakukan. | Ini mungkin sebuah fragmen paging |
Pertama-tama perjelas hubungan hierarki antara Blok, Garis, dan Rentang
Struktur kamus PyMuPDF
Keluaran kamus PyMuPDF secara ketat mengikuti struktur aliran konten PDF, dan hierarki dari luar ke dalam adalah sebagai berikut:
block: Area penyusunan huruf independen pada halaman, seperti paragraf teks, sel tabel, atau legenda.line: Visual satu baris teks di dalamblock.span:lineadalah rangkaian internal karakter berurutan dengan font, ukuran, warna, dan gaya yang sama.
Untuk penjelasan lebih lanjut tentang bidang di setiap lapisan, silakan merujuk ke Dokumentasi resmi PyMuPDF TextPage.
Mengapa peralihan gaya menghasilkan rentang baru?
Selama ada huruf tebal, miring, perubahan warna, atau penggantian font di tengah baris teks (misalnya, karakter Cina dicampur dengan bahasa Inggris dan angka), span baru akan dibuat. span ini termasuk dalam line yang sama dan berbagi garis dasar dan posisi vertikal yang sama.
Apa yang harus diperhatikan pada batas paragraf
Akhir paragraf yang sebenarnya ditandai dengan akhir daftar line dan awal block baru, bukan nomor span. Membingungkan keduanya dapat menyebabkan masalah praktis: misalnya, "Tips penting" salah dikenali sebagai dua kalimat terpisah, sehingga menyebabkan memori terjemahan tidak dapat mencocokkan istilah lengkapnya.
Contoh sintesis: keluaran dan kasus tepi yang benar
Keluaran yang benar
Untuk mengilustrasikan masalahnya, kami membuat skenario sintetik. Misalkan ada baris teks di input PDF: "Harap diperhatikan: Sistem akan restart dalam 5 menit." Diantaranya, "Harap diperhatikan:" menggunakan font tebal, "sistem akan restart dalam 5 menit" kembali ke font Lagu.
Output extractDICT() yang benar harus berisi empat span di bawah satu objek line. bbox dari setiap span sangat tumpang tindih dalam arah vertikal, dan koordinat y dari origin pada dasarnya konsisten. Keempat fragmen ini dirangkai menjadi satu kesatuan semantik yang utuh.
Kualitas masukan rendah
Situasi kesalahan yang umum terjadi adalah PDF yang dipindai belum di-OCR, atau generator PDF menulis setiap karakter Mandarin sebagai objek teks terpisah. Dalam hal ini extractDICT() dapat mengembalikan lusinan span satu kata, dan mungkin ada celah kecil atau tumpang tindih yang tidak teratur di antara bbox tersebut.
Situasi ini tidak dapat diperbaiki hanya dengan penggabungan string karena tidak ada dasar yang dapat diandalkan untuk menyortir dan mengelompokkan. Lebih aman menandai halaman sebagai "data terstruktur berkualitas rendah" dan mengirimkannya ke pemeriksaan manual atau proses OCR khusus daripada memaksakan penggabungan.
Logika penggabungan rentang berdasarkan fitur geometris
Contoh kode
Contoh Python berikut menunjukkan cara meniru struktur keluaran extractDICT() di memori dan mengimplementasikan fungsi penggabungan rentang rekan yang aman. Catatan: Contoh ini membuat data sintetis murni dari memori dan tidak membaca file PDF asli apa pun. Ini hanya digunakan untuk memverifikasi logika algoritma penggabungan.
Untuk penggunaan sebenarnya, harap konfirmasikan bahwa versi PyMuPDF mendukung metode extractDICT (direkomendasikan 1.23.x dan lebih tinggi) dan jalankan di lingkungan ketergantungan Anda yang terkunci.
# 合成示例:演示同行span合并逻辑,非真实PDF解析结果
# 依赖: PyMuPDF (pymupdf) >= 1.23.0,仅用于类型参考,本例纯内存构造
def merge_spans_in_line(line_dict, y_tolerance=2.0):
"""合并同一line内y坐标相近的span,保留原始顺序"""
if not line_dict.get("spans"):
return ""
spans = sorted(line_dict["spans"], key=lambda s: s["bbox"][0]) # 按x排序
merged_text = []
current_y = spans[0]["origin"][1]
buffer = [spans[0]["text"]]
for span in spans[1:]:
y = span["origin"][1]
if abs(y - current_y) <= y_tolerance:
buffer.append(span["text"])
else:
merged_text.append("".join(buffer))
buffer = [span["text"]]
current_y = y
merged_text.append("".join(buffer))
return "\n".join(merged_text)
# 构造合成line数据,模拟四种字体混排(正常情况)
synthetic_line = {
"spans": [
{"text": "请注意:", "bbox": (100, 200, 160, 220), "origin": (100, 215)},
{"text": "系统将在", "bbox": (160, 200, 220, 220), "origin": (160, 215)},
{"text": "5", "bbox": (220, 200, 230, 220), "origin": (220, 215)},
{"text": "分钟后重启。", "bbox": (230, 200, 310, 220), "origin": (230, 215)}
]
}
result = merge_spans_in_line(synthetic_line)
assert result == "请注意:系统将在5分钟后重启。", f"合并失败: {result}"
# 边界测试:y坐标差异超过容差,应视为不同行片段(即使在同一line dict中也应分隔)
bad_line = {
"spans": [
{"text": "上行", "bbox": (100, 200, 140, 220), "origin": (100, 215)},
{"text": "下行", "bbox": (100, 230, 140, 250), "origin": (100, 245)}
]
}
bad_result = merge_spans_in_line(bad_line, y_tolerance=2.0)
# y差值30 > 2.0,应被分隔为两行
assert bad_result == "上行\n下行", f"异常行未正确分隔: {repr(bad_result)}"
Tindakan pencegahan sebelum digunakan
- Nilai 2,0 untuk
y_tolerancehanyalah pengaturan contoh sintetis dan bukan merupakan standar industri. - Dalam proyek sebenarnya, nilai ini dapat dihitung secara dinamis berdasarkan ukuran font rata-rata dokumen; jika
linesendiri telah dibagi dengan benar, biasanya tidak diperlukan verifikasi koordinat y tambahan. - Contoh dalam artikel ini hanya mewakili demonstrasi tingkat kode dan tidak mewakili jaminan semua file nyata atau efek produk.
📊 Perbandingan inti
Tabel berikut membandingkan beberapa metode pemrosesan dan apakah metode tersebut cocok untuk penggabungan otomatis berdasarkan situasi yang diamati, berdasarkan aturan penerimaan di atas.
| Situasi yang diamati | Metode pemrosesan | Apakah cocok untuk penggabungan otomatis? |
|---|---|---|
| Koordinat y bentang dalam garis yang sama adalah konsisten | Penyambungan yang aman | Ya |
| Ada kesenjangan horizontal yang jelas antar bentang | Sisipkan spasi atau tab setelah memeriksa spasi | Berhati-hatilah dan perlu aturan |
| Rumus sebaris, superskrip, dan subskrip menyebabkan perbedaan besar pada koordinat y | Pertahankan struktur bentang asli | TIDAK |
| Rentang kata tunggal dan bbox tidak berurutan | Tandai kualitas rendah, ubah ke manual atau OCR | TIDAK |
| Teks yang berkesinambungan secara semantik melintasi blok | Penilaian berdasarkan konteks | Tidak, bantuan NLP diperlukan |
Kriteria penerimaan dan batasan tinjauan manual
| Amati fenomena | Kemungkinan alasannya | keputusan pemrosesan | Apakah akan menerapkan penggabungan otomatis |
|---|---|---|---|
| Beberapa bentang dalam satu garis mempunyai koordinat y yang sama | Peralihan font/warna | Splicing yang aman span.teks | Ya |
| Terdapat celah horizontal yang jelas antar bentang (>lebar ruang) | Karakter tab dan sisa kolom | Periksa spasi bbox, masukkan spasi atau tab | Berhati-hatilah dan perlu aturan |
| Perbedaan koordinat rentang y dalam baris yang sama > ukuran font 10% | Rumus sebaris, superskrip, dan subskrip | Pertahankan struktur bentang asli tanpa penggabungan | TIDAK |
| Rentang kata tunggal dan bbox tidak berurutan | PDF yang dipindai atau rusak | Tandai sebagai kualitas rendah, ubah ke manual atau OCR | TIDAK |
| Kontinuitas semantik teks antar blok | Istirahat halaman | Penggabungan lintas blok memerlukan penilaian kontekstual | Tidak, bantuan NLP diperlukan |
Tabel ini hanya mencakup verifikasi struktural pada tingkat demonstrasi kode, dan efek ujung ke ujung perlu dikombinasikan dengan model bahasa atau pengambilan sampel manual. Penggabungan otomatis tidak boleh digunakan untuk dokumen sensitif format seperti kontrak hukum, rekam medis, dll., kecuali diverifikasi oleh pakar domain.
Sebelum digunakan, harap siapkan sendiri PDF uji desensitisasi, jalankan page.get_text("dict", sort=True) untuk mengekspor JSON, lalu periksa setiap item.
Digunakan untuk pengecekan sebelum penerjemahan dokumen
Pertama-tama periksa urutan halaman, lokasi sumber, dan integritas teks, lalu kirimkan sampel yang tidak peka ke proses penerjemahan. Setelah diterjemahkan, Anda tetap perlu memeriksa apakah judul, teks, dan ilustrasi sudah sesuai dengan benar, bukan hanya apakah teksnya lancar.
OmniDoc (portal produk) menyediakan portal terjemahan dokumen multi-format, dan situs resminya memperkenalkan fungsi OCR, glosarium, dan perbandingan bilingual. Untuk tim yang ingin bekerja langsung dari file, ini adalah jalur yang layak dievaluasi dengan sampel kehidupan nyata. Harap gunakan file yang tidak peka dan Anda mempunyai izin untuk mengunggahnya, dan gunakan item centang dalam artikel ini untuk meninjau hasilnya. Tidak ada klaim di sini bahwa OmniDoc menggunakan perpustakaan sumber terbuka atau algoritma internal dalam artikel ini, dan contoh tersebut juga tidak menggantikan pengujian kinerja produk.
🎯 Metode mana yang cocok untuk Anda?
Jika Anda hanya ingin mengatur teks pada baris yang sama
- Kelompokkan berdasarkan
line, dan sambungkanspan.textdengan aman jika koordinat y konsisten.
Jika Anda menemukan rumus sebaris atau superskrip
- Pertahankan struktur
spanasli tanpa penggabungan.
Jika Anda berurusan dengan pindaian atau PDF dengan banyak rentang kata tunggal
- Tandai sebagai kualitas rendah terlebih dahulu, lalu transfer ke pemeriksaan manual atau proses OCR khusus.
Jika Anda ingin melakukan terjemahan lintas blok atau lintas halaman
- Berdasarkan penilaian kontekstual, tidak tepat jika dilakukan penggabungan secara langsung secara otomatis.
❓ Pertanyaan yang Sering Diajukan (FAQ)
1. Satu baris teks dibagi menjadi beberapa bentang. Apakah harus segmentasi?
Belum tentu, sebagian besar disebabkan oleh perubahan font, ukuran font, atau warna. span dalam line yang sama memiliki garis dasar dan posisi vertikal yang sama.
2. Apa yang harus saya baca di akhir paragraf?
Lihat apakah daftar line berakhir dan block baru dimulai, bukan nomor span.
3. Bisakah penggabungan string digunakan untuk memperbaiki masalah rentang satu kata?
Tidak direkomendasikan. Kasus-kasus seperti ini tidak memiliki dasar yang dapat diandalkan untuk menyortir dan mengelompokkan, dan lebih bijaksana untuk menandai kasus-kasus tersebut sebagai kasus berkualitas rendah dan meneruskannya ke proses manual atau OCR.
4. Berapa y_tolerance yang harus disetel saat menggabungkan?
2.0 dalam contoh hanyalah pengaturan contoh sintetik saja dan bukan merupakan standar industri. Item sebenarnya dapat dihitung secara dinamis berdasarkan ukuran font rata-rata, atau langsung mempercayai pengelompokan line.
5. Apakah merger otomatis dapat digunakan dalam kontrak hukum?
Tidak cocok kecuali diverifikasi oleh pakar domain.
📝 Ringkasan
Kunci untuk menilai apakah span dapat digabungkan adalah dengan melihat terlebih dahulu struktur line dan block, lalu melihat posisi geometrinya. Saat menemukan rumus, dokumen yang dipindai, atau semantik lintas blok, lebih baik menyimpannya apa adanya atau mengonversinya secara manual daripada menyatukannya secara paksa.


