Partage
  • Partager sur Facebook
  • Partager sur Twitter

Comparer des occurrences deux à deux dans un texte

    13 mai 2013 à 14:41:18

    Bonjour,

    J'écris un script qui me permet de traiter des fichiers xml, obtenus à partir d'un parseur pdf. Grosso-modo, je fais des rechercher-remplacer, parfois récursifs. Mais je voudrais ajouter une nouvelle fonctionnalité sur laquelle je bloque.

    Dans mon fichier, il y a, entre autres, des balises de type

    <textline bbox="292.750,639.422,299.250,654.060">

    Je voudrais parcourir le fichier, et pour chaque occurrence d'une balise textline, la comparer à la précédente. (Les coordonnées me permettent ainsi de calculer l'espacement entre les lignes).

    Un exemple de mon fichier :

    <textline bbox="292.750,639.422,299.250,654.060">
    <text font="GaramondThree" bbox="292.750,639.422,299.250,654.060" size="14.638">*</text>
    </textline>
    <textline bbox="189.283,611.422,422.550,626.060">
    <text font="GaramondThree" bbox="189.283,611.422,195.783,626.060" size="14.638">Bla bla bla bla bla</text>
    </textline>
    <textline bbox="169.441,597.422,257.162,612.060">
    <text font="GaramondThree" bbox="169.441,597.422,175.941,612.060" size="14.638">blablabla</text>
    </textline>
    

    Mais je ne sais pas comment procéder !

    Avez-vous une idée ?

    Merci beaucoup.


    • Partager sur Facebook
    • Partager sur Twitter
      13 mai 2013 à 16:25:04

      Salut,

      Pour moi tu peux faire

      balise = '<textline'
      bboxAnterieur = ""
      
      for line in fichier:
          if balise in line:
              comparer(line, bboxAnterieur)
              bboxAnterieur = line[:]      # [:] pour copier line et pas juste attribuer un nouveau nom.
      

      Après si ton vrai souci c'est comment implémenter comparer(), faudrait être plus précis sur ce qu'il faut faire ;)

      Edit : en fait [:] est inutile puisque les chaînes de caractères sont non mutables...

      -
      Edité par haako 13 mai 2013 à 16:39:13

      • Partager sur Facebook
      • Partager sur Twitter
      If you had infinite Shakespeares with infinite typewriters I bet not one of them would ever type the complete works of a monkey.
        13 mai 2013 à 19:32:58

        Bonjour,

        Merci de ta réponse.

        S'il y a plusieurs balises textline dans la même ligne, ça ne va pas marcher non ? Il me semble que

        if balise in line:

        ne cherche que la première occurrence, et qu'on passe ensuite à la ligne suivante.

        Est-ce qu'il n'y a pas un moyen de parcourir toutes les occurrences les unes après les autres ?

        • Partager sur Facebook
        • Partager sur Twitter
          13 mai 2013 à 20:16:29

          Ah effectivement.

          Dans ce cas on pourrait utiliser string.count(substring) :

          for line in fichier:
              if balise in line:
                  comparer(line, bboxAnterieur)
                  if line.count(balise) == 1:
                      bboxAnterieur = line
                  else:
                      comparer(line[line.find(balise:len(balise))],
                               line[line.rfind(balise):])
                      bboxAnterieur = line

          Bon là ça ne marche pas pour plus de deux <textline par ligne ^^

          Pour plus je pense qu'extraire l'index du début de chaque occurence avec une boucle while dans le else serait viable.

          Edit : code corrigé

          -
          Edité par haako 13 mai 2013 à 20:21:50

          • Partager sur Facebook
          • Partager sur Twitter
          If you had infinite Shakespeares with infinite typewriters I bet not one of them would ever type the complete works of a monkey.
            13 mai 2013 à 20:23:06

            À la réflexion ma solution est pas géniale, je vais y réfléchir.

            Edit : bon ça devrait faire l'affaire :

            for line in fichier:
                if balise in line:
                    comparer(line,bboxAnterieur)
                    if line.count(balise) > 1:
                        listeIndex = [i.start() for i in
                                      re.finditer(balise, line)]
                        occurenceAnt = line[listeIndex[0]:longueur]
                        for i in listeIndex:
                            comparer(occurenceAnt,
                                       line[i:i+longueur])
                            occurenceAnt = line[i:i+longueur]
                        bboxAnterieur = line[listeIndex[-1]:
                                             listeIndex[-1]+longueur]
                    else:
                        bboxAnterieur = line

            avec import re, et la limitation de renseigner longueur, variable contenant la longueur de tes balises qui doit être constante (sinon il faudra chercher à chaque fois où est la fin de la balise dans la ligne).

            Bon le code peut sans doute être grandement amélioré.

            Une manière plus simple aurait peut-être été de scinder chaque ligne selon les balises textline...

            -
            Edité par haako 13 mai 2013 à 20:45:54

            • Partager sur Facebook
            • Partager sur Twitter
            If you had infinite Shakespeares with infinite typewriters I bet not one of them would ever type the complete works of a monkey.
              14 mai 2013 à 15:16:44

              Merci de ta réponse.

              Je n'avais pas pensé à ça :

              line.count(balise)

              Du coup effectivement, il suffit de faire une boucle avec le nombre d'occurrence sur une ligne.

              Je réfléchis encore un peu, je cherche le temps de m'y remettre et je reviendrai noter ce que j'ai trouvé.

              • Partager sur Facebook
              • Partager sur Twitter

              Comparer des occurrences deux à deux dans un texte

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown