La même ligne de texte est divisée en plus de dix travées par PyMuPDF ? Ceci détermine s'il doit être fusionné
PyMuPDF divise la même ligne de mots en plus d'une douzaine de travées. La plupart du temps, la police, la taille ou le style de police ont changé, pas nécessairement la segmentation. Cet article explique comment distinguer les changements de style et les limites de paragraphe, et donne des exemples de logique de fusion et de formulaire d'acceptation pour éviter de découper une phrase lors de la traduction.
Lorsque vous utilisez extractDICT() de PyMuPDF pour extraire du texte PDF, vous constaterez peut-être qu'une phrase cohérente est découpée en sept, huit span ou plus dans le résultat renvoyé. Il ne s'agit généralement pas d'une erreur d'analyse, mais d'un véritable reflet de la structure sous-jacente du PDF : le changement de police, les changements de couleur ou les ajustements de style locaux peuvent interrompre le flux du texte lors du rendu.
Si ce « découpage de style » est confondu avec une « segmentation de paragraphe », un nettoyage, une traduction ou une récupération ultérieure entraînera facilement des erreurs de segmentation de phrases. Cet article explique comment distinguer les changements de style des limites de paragraphe, donne un exemple fusionné de logique de fusion et fournit un formulaire d'acceptation pour vous aider à éviter de découper une phrase.
Une ligne de texte dans le PDF est divisée en plusieurs plages. Faut-il les fusionner ? Conclusion en une phrase
Lorsqu'il y a plusieurs span dans le même line et que les coordonnées y sont les mêmes, il s'agit principalement de la police, de la taille de la police ou du changement de couleur, qui peuvent être épissés en toute sécurité ; la limite du paragraphe doit être basée sur la structure de block et line, et non sur le nombre de span.
| votre situation | Pratiques recommandées | raison |
|---|---|---|
| Plusieurs travées au sein de la même ligne ont les mêmes coordonnées y | Span d'épissage sécurisé.text | Principalement changement de police ou de couleur |
| Il y a un écart horizontal évident entre les travées | Vérifiez l'espacement des bbox et insérez des espaces ou des tabulations si nécessaire | Peut être un caractère de tabulation ou un résidu de saut de colonne, nécessite des règles |
| La différence entre les coordonnées y des travées au sein d'une même ligne dépasse 10 % de la taille de la police. | Conserver la structure de travée d'origine sans fusionner | Peut être des formules en ligne ou des indices |
| L'étendue d'un seul mot et la bbox ne sont pas ordonnées | Marquer comme faible qualité, convertir en manuel ou OCR | Manque de base fiable pour le tri et le regroupement |
| Texte sémantiquement continu à travers les blocs | Un jugement contextuel est requis et la fusion automatique n’est pas effectuée. | Il peut s'agir d'un fragment de pagination |
Clarifiez d'abord la relation hiérarchique entre Block, Line et Span
Structure du dictionnaire de PyMuPDF
La sortie du dictionnaire de PyMuPDF suit strictement la structure de flux de contenu du PDF, et la hiérarchie de l'extérieur vers l'intérieur est la suivante :
block: Une zone de composition indépendante sur la page, comme un paragraphe de texte, une cellule de tableau ou une légende.line: ligne unique de texte visuel à l'intérieur deblock.span:lineest une séquence interne de caractères consécutifs avec la même police, la même taille, la même couleur et le même style.
Pour plus de descriptions des champs de chaque couche, veuillez vous référer à Documentation officielle de PyMuPDF TextPage.
Pourquoi le changement de style génère-t-il un nouveau span ?
Tant qu'il y a du gras, de l'italique, un changement de couleur ou un remplacement de police au milieu d'une ligne de texte (par exemple, les caractères chinois sont mélangés avec l'anglais et les chiffres), un nouveau span sera généré. Ces span appartiennent au même line et partagent la même ligne de base et la même position verticale.
Que faut-il regarder au niveau des limites des paragraphes
La vraie fin d'un paragraphe est marquée par la fin de la liste line et le début d'un nouveau block, et non par le numéro de span. Confondre les deux peut entraîner des problèmes pratiques : par exemple, "Conseil important" est reconnu par erreur comme deux phrases distinctes, ce qui empêche la mémoire de traduction de faire correspondre le terme complet.
Exemple de synthèse : sortie correcte et cas extrêmes
Corriger le résultat
Pour illustrer le problème, nous construisons un scénario synthétique. Supposons qu'il y ait une ligne de texte dans le PDF d'entrée : "Veuillez noter : le système redémarrera dans 5 minutes." Parmi eux, "Veuillez noter :" utilise une police en gras, "le système redémarrera dans 5 minutes" revient à la police Song.
La sortie extractDICT() correcte doit contenir quatre span sous un objet line. Les bbox de chaque span se chevauchent fortement dans la direction verticale et les coordonnées y de origin sont fondamentalement cohérentes. Ces quatre fragments sont assemblés pour former une unité sémantique complète.
Entrée de mauvaise qualité
Une situation d'erreur typique est que le PDF numérisé n'a pas été traité par OCR ou que le générateur de PDF écrit chaque caractère chinois comme un objet texte distinct. Dans ce cas, extractDICT() peut renvoyer des dizaines de span à un seul mot, et il peut y avoir de petits écarts ou des chevauchements irréguliers entre leurs bbox.
Cette situation ne peut pas être résolue simplement par concaténation de chaînes car il n’existe aucune base fiable pour le tri et le regroupement. Il est plus sûr de marquer la page comme « données structurées de mauvaise qualité » et de l'envoyer à une relecture manuelle ou à un processus OCR dédié plutôt que de forcer une fusion.
Logique de fusion Span basée sur des caractéristiques géométriques
Exemple de code
L'exemple Python suivant montre comment émuler la structure de sortie de extractDICT() en mémoire et implémenter une fonction de fusion sécurisée entre homologues. Remarque : Cet exemple construit des données synthétiques uniquement à partir de la mémoire et ne lit aucun fichier PDF réel. Il est uniquement utilisé pour vérifier la logique de l'algorithme de fusion.
Pour une utilisation réelle, veuillez confirmer que la version PyMuPDF prend en charge la méthode extractDICT (1.23.x et supérieur recommandé) et exécutez-la dans votre propre environnement de dépendances verrouillé.
# 合成示例:演示同行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)}"
Précautions avant utilisation
- Une valeur de 2,0 pour
y_toleranceest uniquement un exemple synthétique de paramètre et ne constitue pas une norme industrielle. - Dans les projets réels, cette valeur peut être calculée dynamiquement en fonction de la taille moyenne de la police du document ; si
linelui-même a été correctement divisé, il n'est généralement pas nécessaire de procéder à une vérification supplémentaire des coordonnées y. - Les exemples de cet article représentent uniquement des démonstrations au niveau du code et ne représentent pas une garantie de tous les fichiers réels ou effets du produit.
📊 Comparaison de base
Le tableau suivant compare plusieurs méthodes de traitement et indique si elles conviennent à la fusion automatique en fonction de la situation observée, sur la base des règles d'acceptation ci-dessus.
| Situation observée | Méthode de traitement | Est-il adapté à la fusion automatique ? |
|---|---|---|
| Les coordonnées y des travées au sein d'une même ligne sont cohérentes | Épissage sécurisé | Oui |
| Il y a un écart horizontal évident entre les travées | Insérer des espaces ou des tabulations après avoir vérifié l'espacement | Soyez prudent et avez besoin de règles |
| Les formules en ligne, les exposants et les indices entraînent de grandes différences dans les coordonnées y | Conserver la structure de travée d'origine | Non |
| L'étendue d'un seul mot et la bbox ne sont pas ordonnées | Signaler une mauvaise qualité, convertir en manuel ou OCR | Non |
| Texte sémantiquement continu à travers les blocs | Jugement basé sur le contexte | Non, une assistance PNL est requise |
Critères d'acceptation et limites de révision manuelle
| Observer les phénomènes | Raisons possibles | décision de traitement | S'il faut appliquer la fusion automatique |
|---|---|---|---|
| Plusieurs travées au sein de la même ligne ont les mêmes coordonnées y | Changement de police/couleur | Span d'épissage sécurisé.text | Oui |
| Il y a un écart horizontal évident entre les travées (>largeur de l'espace) | Caractères de tabulation et résidus de colonne | Vérifiez l'espacement des bbox, insérez des espaces ou des tabulations | Soyez prudent et avez besoin de règles |
| Différence de coordonnées y au sein d'une même ligne > taille de police 10 % | Formules en ligne, exposants et indices | Conserver la structure de travée d'origine sans fusionner | Non |
| L'étendue d'un seul mot et la bbox ne sont pas ordonnées | PDF numérisé ou endommagé | Marquer comme faible qualité, convertir en manuel ou OCR | Non |
| Continuité sémantique du texte entre les blocs | Saut de page | La fusion entre blocs nécessite un jugement contextuel | Non, une assistance PNL est requise |
Ce tableau ne couvre que la vérification structurelle au niveau de la démonstration de code, et l'effet de bout en bout doit être combiné avec des modèles de langage ou un échantillonnage manuel. La fusion automatique ne doit pas être utilisée pour les documents sensibles au format tels que les contrats juridiques, les dossiers médicaux, etc., sauf vérification par un expert du domaine.
Avant utilisation, veuillez préparer vous-même le PDF du test de désensibilisation, exécutez page.get_text("dict", sort=True) pour exporter JSON, puis vérifiez chaque élément.
Utilisé pour vérifier avant la traduction du document
Vérifiez d’abord l’ordre des pages, l’emplacement de la source et l’intégrité du texte, puis soumettez le même échantillon désensibilisé au processus de traduction. Après la traduction, vous devez encore vérifier si le titre, le texte et les illustrations correspondent correctement, et pas seulement si le texte est fluide.
OmniDoc (portail produit) fournit un portail de traduction de documents multiformat et le site officiel présente des fonctions d'OCR, de glossaire et de comparaison bilingue. Pour les équipes qui souhaitent travailler directement à partir des fichiers, il s’agit d’une voie qui mérite d’être évaluée avec des échantillons réels. Veuillez utiliser les fichiers désensibilisés que vous êtes autorisé à télécharger et utilisez les éléments de vérification de cet article pour examiner les résultats. Rien ne prétend ici qu'OmniDoc utilise les bibliothèques open source ou les algorithmes internes de cet article, et l'exemple ne remplace pas non plus les tests de performances du produit.
🎯 Quelle méthode vous convient ?
Si vous souhaitez simplement organiser le texte sur la même ligne
- Regroupez par
lineet épissez en toute sécuritéspan.textlorsque les coordonnées y sont cohérentes.
Si vous rencontrez des formules en ligne ou des exposants
- Conserver la structure
spand'origine sans fusionner.
Si vous traitez des scans ou des PDF comportant de nombreux mots composés d'un seul mot
- Marquez d'abord comme mauvaise qualité, puis transférez vers une relecture manuelle ou un processus OCR dédié.
Si vous souhaitez effectuer une traduction multi-blocs ou multi-pages
- Sur la base d'un jugement contextuel, il n'est pas approprié de fusionner directement et automatiquement.
❓ Questions fréquemment posées (FAQ)
1. Une ligne de texte est divisée en plusieurs étendues. Faut-il procéder à une segmentation ?
Pas nécessairement, cela est principalement dû à des changements de police, de taille ou de couleur. Les span au sein du même line partagent la même ligne de base et la même position verticale.
2. Que dois-je lire à la fin du paragraphe ?
Vérifiez si la liste line se termine et qu'un nouveau block commence, pas le numéro de span.
3. La concaténation de chaînes peut-elle être utilisée pour résoudre le problème de l'étendue d'un seul mot ?
Non recommandé. De tels cas ne disposent pas d’une base fiable pour le tri et le regroupement, et il est plus prudent de les signaler comme étant de mauvaise qualité et de les transmettre à un processus manuel ou OCR.
4. À quel point y_tolerance doit-il être défini lors de la fusion ?
Le 2.0 dans l’exemple est uniquement un exemple de paramètre synthétique et ne constitue pas une norme industrielle. Les éléments réels peuvent être calculés dynamiquement en fonction de la taille de police moyenne ou faire directement confiance au regroupement de line.
5. La fusion automatique peut-elle être utilisée dans les contrats juridiques ?
Ne convient pas sauf vérification par des experts du domaine.
📝Résumé
La clé pour juger si span peut être fusionné est d'examiner d'abord la structure de line et block, puis d'examiner la position géométrique. Lorsque vous rencontrez des formules, des documents numérisés ou une sémantique de blocs croisés, il est préférable de les conserver tels quels ou de les convertir manuellement plutôt que de les assembler de force.


