0
votes

soulignant les mots dans un fichier DOCX utilisant Python-DOCX donne des résultats incorrects

Je voudrais mettre en évidence des mots spécifiques dans un document MS Word (ici donné comme négativiviste) et laisser le reste du document tel qu'il était précédemment. J'ai essayé d'adopter de ce un mais je ne peux pas le faire courir comme il se doit : XXX

AS l'exemple J'utilise ce texte (dans un fichier Word DOCX):

chapitre 1

il y a des siècles il y a vécu -

"Un roi!" mes petits lecteurs diront immédiatement.

Non, les enfants, vous vous trompez. Il était une fois un morceau de bois. Ce n'était pas un morceau de bois cher. Loin de là. Juste un bloc commun de bois de chauffage, une de ces bûches épaisses et solides qui sont placées sur le feu en hiver pour faire des chambres froides confortables et chaudes.

Il y a plusieurs problèmes avec mon code:

1) La première phrase fonctionne, mais la deuxième phrase est à deux reprises. Pourquoi?

2) Le format est perdu d'une manière ou d'une autre dans la partie où je souligne. J'aurais peut-être besoin de copier les propriétés de la course d'origine dans les nouveaux créées, mais comment puis-je faire cela?

3) Je perds le terminal "-"

4) Dans le dernier paragraphe mis en surbrillance, le "confortable et chaud" est manquant ...

Ce dont j'aurais besoin, c'est d'alguer une solution pour ces problèmes ou peut-être que je suis impérié et il y a un moyen beaucoup plus facile de faire la mise en évidence? (quelque chose comme doc.Highlight ({"roi": "rose"} mais je n'ai rien trouvé dans la documentation)?


0 commentaires

3 Réponses :


2
votes

Vous n'êtes pas trop longueur, c'est un problème difficile; C'est une forme du problème de recherche et de remplacement.

Le texte cible peut être localisé assez facilement en recherchant paragraphe.text , mais le remplaçant de le remplacement (ou dans votre cas ajout de formatage) tout en conservant les autres formatage requiert un accès au Exécuter Niveau, des deux que vous avez découverts.

Il y a quelques complications cependant, ce qui est ce qui le rend difficile:

  • Il n'y a aucune garantie que votre chaîne cible "Recherche" est entièrement située en une seule fois. Donc, vous devrez trouver la course contenant le Démarrer de votre chaîne cible et la course contenant la extrémité de votre chaîne cible, ainsi que tout intermédiaire.

    Ceci pourrait être facilité en utilisant des décalages de caractères, comme "King" apparaît sur le caractère offset 3 dans '"Un roi!" ... ', et a une longueur de 4, puis identifiant quelle analyse contient le caractère 3 et qui contient caractère (3 + 4).

  • liée à la première complication, rien ne garantit que toutes les exécutions dans lesquelles la chaîne cible apparaît partiellement sont formatées les mêmes. Par exemple, si votre chaîne cible était "A Bold Word ", la version mise à jour (après avoir ajouté la surbrillance) nécessiterait au moins trois exécute, une pour" A ", une Pour "Bold", et un pour "Word" (BTW, qui exécutent chacun des deux caractères spatiaux apparaissant ne changera pas comment ils apparaissent).

    Si vous acceptez la simplification que la chaîne cible sera toujours un mot unique, vous pouvez envisager la simplification de l'exécution de la mise en place de la mise en place du premier caractère (première exécution) de la cible trouvée, qui est probablement l'habituel. approche.

    Je suppose donc qu'il y a quelques approches possibles, mais il serait difficile de "normaliser" les courses de chaque paragraphe contenant la chaîne cible, de sorte que la chaîne cible est apparue dans une exécution distincte. Ensuite, vous pouvez simplement appliquer la mise en évidence à cette course et vous obtiendrez le résultat que vous vouliez.

    Pour être d'une aide plus utile, vous devrez réduire les problèmes et fournir des entrées et des sorties spécifiques. Je commencerais avec le premier (Perdre peut-être le "-") (dans une question séparée, peut-être liée à partir d'ici), puis procédez à un par un à un jusqu'à ce que tout fonctionne. Il demande trop qu'un répondant produise son propre cas de test :)

    alors vous auriez une question comme: "Je gère la chaîne:" Il y a des siècles ... - "à travers ce code et le trail" - "disparaît ...", qui est beaucoup plus facile pour les gens raisonner à travers.

    Une autre bonne étape suivante pourrait être d'imprimer le texte de chaque course, afin que vous ayez une idée de la façon dont ils sont brisés. Cela peut vous donner un aperçu de l'endroit où cela ne fonctionne pas.


2 commentaires

Merci pour votre réponse! Je serais heureux si je pouvais simplement obtenir la version de base en cours d'exécution (ce qui signifie que je suppose qu'un mot ne fait toujours qu'une partie d'une course). De cela, je pense que je serais capable de le faire sortir ... Je pense que le paragraphe.runs.clear () pourrait ne pas faire le bon travail (si je imprime le paragraphe.text avant et après le paragraphe.runs.clear ( ) Les résultats sont les mêmes ...) qui provoque-t-on les duplications - savez-vous que je peux supprimer toutes les pistes d'un phare? Parce que je devrai les supprimer en quelque sorte afin de remplir le paragraphe avec de nouvelles pistes? (pourrait également résoudre le problème "-")


Deviner! Le clair doit être appliqué au paragraphe et non paragraphe.Runs. Continuera à travailler dessus et postez la solution si je suis capable de le faire!



0
votes

J'ai fait face à un problème similaire où je devais mettre en évidence un ensemble de mots dans un document. J'ai modifié certaines parties du code de l'OP et je suis maintenant capable de mettre en évidence les mots sélectionnés correctement.

SELA SAide dans les commentaires: paragraphe.runs.clear () a été remplacé par paragraphe.clear () . Et j'ai ajouté quelques lignes à la partie suivante du code: xxx

pour obtenir ceci: xxx

en itération Sur les currours, nous extrayons le contenu du texte de la course et l'ajoutons au paragraphe afin que nous ayons donc besoin de mettre à nouveau ces mots.


0 commentaires

0
votes

Je sais que ce n'est pas la même bibliothèque, mais en utilisant la bibliothèque Wincom32, vous pouvez mettre en évidence toutes les instances du mot dans une plage spécifique à la fois. Le code ci-dessous prendra tout en évidence tous les hits.

import win32com.client as win32

word = win32.gencache.EnsureDispatch('Word.Application');word.Visible = True
word = word.Documents.Open("test.docx")

strage = word.Range(Start=0, End=0) #change this range to shorten the replace
strage.Find.Replacement.Highlight = True
strage.Find.Execute(FindText="the",Replace=2,Format=True)


0 commentaires