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 AndaPraktik yang direkomendasikanalasan
Beberapa bentang dalam satu garis mempunyai koordinat y yang samaSplicing yang aman span.teksSebagian besar pergantian font atau warna
Ada kesenjangan horizontal yang jelas antar bentangPeriksa spasi bbox dan masukkan spasi atau tab jika perluMungkin sisa karakter tab atau kolom pecah, memerlukan aturan
Perbedaan koordinat y bentang dalam baris yang sama melebihi 10% ukuran fontPertahankan struktur bentang asli tanpa penggabunganMungkin berupa rumus sebaris atau subskrip
Rentang kata tunggal dan bbox tidak berurutanTandai sebagai kualitas rendah, ubah ke manual atau OCRKurangnya dasar yang dapat diandalkan untuk menyortir dan mengelompokkan
Teks yang berkesinambungan secara semantik melintasi blokPenilaian 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 dalam block.
  • span: line adalah 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_tolerance hanyalah pengaturan contoh sintetis dan bukan merupakan standar industri.
  • Dalam proyek sebenarnya, nilai ini dapat dihitung secara dinamis berdasarkan ukuran font rata-rata dokumen; jika line sendiri 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 diamatiMetode pemrosesanApakah cocok untuk penggabungan otomatis?
Koordinat y bentang dalam garis yang sama adalah konsistenPenyambungan yang amanYa
Ada kesenjangan horizontal yang jelas antar bentangSisipkan spasi atau tab setelah memeriksa spasiBerhati-hatilah dan perlu aturan
Rumus sebaris, superskrip, dan subskrip menyebabkan perbedaan besar pada koordinat yPertahankan struktur bentang asliTIDAK
Rentang kata tunggal dan bbox tidak berurutanTandai kualitas rendah, ubah ke manual atau OCRTIDAK
Teks yang berkesinambungan secara semantik melintasi blokPenilaian berdasarkan konteksTidak, bantuan NLP diperlukan

Kriteria penerimaan dan batasan tinjauan manual

Amati fenomenaKemungkinan alasannyakeputusan pemrosesanApakah akan menerapkan penggabungan otomatis
Beberapa bentang dalam satu garis mempunyai koordinat y yang samaPeralihan font/warnaSplicing yang aman span.teksYa
Terdapat celah horizontal yang jelas antar bentang (>lebar ruang)Karakter tab dan sisa kolomPeriksa spasi bbox, masukkan spasi atau tabBerhati-hatilah dan perlu aturan
Perbedaan koordinat rentang y dalam baris yang sama > ukuran font 10%Rumus sebaris, superskrip, dan subskripPertahankan struktur bentang asli tanpa penggabunganTIDAK
Rentang kata tunggal dan bbox tidak berurutanPDF yang dipindai atau rusakTandai sebagai kualitas rendah, ubah ke manual atau OCRTIDAK
Kontinuitas semantik teks antar blokIstirahat halamanPenggabungan lintas blok memerlukan penilaian kontekstualTidak, 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 sambungkan span.text dengan aman jika koordinat y konsisten.

Jika Anda menemukan rumus sebaris atau superskrip

  • Pertahankan struktur span asli 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.

Coba sekarang: Unggah dokumen untuk memulai penerjemahan, dengan tetap mempertahankan tata letak aslinya

Diperbarui 2026-11-15