IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

RegEx extraction entre simple quote


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2003
    Messages : 115
    Points : 60
    Points
    60
    Par défaut RegEx extraction entre simple quote
    Bonjour

    Je cherche à récupérer d'un fichier kml les coordonnées d'un trajet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	<Placemark>
    		<name>ALPHA-Cheminement</name>
    		<styleUrl>#msn_ylw-pushpin</styleUrl>
    		<LineString>
    			<tessellate>1</tessellate>
    			<coordinates>
    				3.78919818067865,49.23157613507813,0 3.791865127977232,49.23093688390484,0 3.794833704929468,49.22795011803071,0   
    			</coordinates>
    		</LineString>
    	</Placemark>
    J'utilise IXMLNode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    procedure TUnit.LoadXML(XMLNode: IXMLNode; TreeNode: TTreeNode);
    var
      K                 : integer;
      LNode1        : IXMLNode;
      LNode2        : IXMLNode;
      SplittedPts   : TStringDynArray;
      NodeTree     : TTreeNode;
      ArrayPts      : string;
    begin
      // Recursive call
      if XmlNode.NodeName = 'Placemark' then
      begin
        LNode1 := XmlNode.ChildNodes.FindNode('LineString');
        if (LNode1 <> Nil) then
        begin
          LNode2      := LNode1.ChildNodes.FindNode('coordinates');
          SplittedPts := SplitString(LNode2.NodeValue,' ');
        end;
      end;
      if XMLNode.HasChildNodes then
        for I := 0 to XMLNode.ChildNodes.Count - 1 do
          LoadXML(XMLNode.ChildNodes.Nodes [I], NodeTree);
    end;
    Je récupère bien les coordonnées dans SplittedPts mais la chaîne comporte des caractères ACSII supplémentaires, #$A#9#9#9#9, en début et en fin de chaîne (précédé d'une virgule et d'un espace)

    (#$A#9#9#9#9'3.78919818067865,49.23157613507813,0', '3.791865127977232,49.23093688390484,0', '3.794833704929468,49.22795011803071,0', #$A#9#9#9)
    Les coordonnées étant situés entre les simples quotes, j'ai essayer d'extraire ces caractères par une expression régulière avec le pattern
    const PATTERN = '\''.*\''';
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        for K := 0 to NbPts do
          begin
            Expr   := TRegEx.Create(PATTERN);
            Match := expr.Match(SplittedPts[K]);
            if Match.Success then
              for Group in Match.Groups do
                ArrayPts := Group.value
            else
              ArrayPts := '';
    Si je teste le pattern \'.*\' sur un site en ligne, j'extrais bien les coordonnées.
    Le problème est que la traduction du simple quote dans Delphi n'est pas reconnu et Match.Success = false

    J'ai aussi essayé d'utiliser StringReplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ArrayPts := StringReplace(SplittedPts[K],'#$A#9#9#9#9','',[rfReplaceAll, rfIgnoreCase]);
    Mais ces caractères ne sont pas supprimés

    Merci de vos idées

  2. #2
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Utilise un stringreplace pour supprimer les caractères indésirables

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Remplacer les apostrophes par un autre caractère moins problématique par exemple §
    changer alors l'expression régulière pour le nouveau pattern, const PATTERN = '§.*§';
    même si c'est un peu arraché par les cheveux

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2003
    Messages : 115
    Points : 60
    Points
    60
    Par défaut
    Bonjour

    La solution String replace a déjà été testée, (voir la dernier phrase du post).
    Elle n'est pas fonctionnelle. Je ne comprend pas pourquoi mais aucun des caractères indésirables sont remplacés alors que la fonction fonctionne normalement sur les caractères entre les quotes.

    C'est idem pour les quotes, je ne peux pas les substituer par un autre caractère
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ArrayPts := StringReplace(SplittedPts[K],'''','$',[rfReplaceAll, rfIgnoreCase]);
    #$A#9#9#9#9'3.78919818067865,49.23157613507813,0'
    La chaîne n'est pas modifiée
    Si je poursuis en extrayant les coordonnées et que je fais un ShowMessage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            SplittedCoord := SplitString(ArrayPts,',');
            ShowMessage('Chaîne = '+SplittedCoord[0]);
    La fenêtre affiche que la longitude (3.78919818067865) ces caractères antérieurs ne sont pas visibles
    C'est comme si ces caractères n'appartiennent pas à la chaîne. Est des caractères d'encodage ?
    Mais je ne peux pas convertir cette chaîne en numérique par StrToFloat(SplittedCoord[0])
    Avec un point d’arrêt je visualise que la variable SplittedCoord[0] comporte toujours ces caractères
    #$A#9#9#9#9'3.78919818067865'
    Merci

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 764
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Tu pourrais aussi passer par Trim.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ArrayPts    := LNode2.NodeValue;
    SplittedPts := SplitString(ArrayPts.Trim([#$A, #$9]));
    Mais l'idéal serait d'avoir un XML correctement formaté. L'indentation du contenu de <coordinates> n'a pas lieu d'être.

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    Bonjour,
    Ne dirait-on point que ce sont les LineFeed et Tabulations qui réalisent l'indentation ?
    Tu splittes selon les espaces et recueille donc ce qu'il y a avant et après sous forme de caractères non imprimables.
    Et si c'est la vue dans l'EDI (l'inspecteur de variables) qui nous montre les différentes chaînes du StringList, les groupes de 3 points apparaissent chacun entre ' car ce sont des ASCII imprimables.
    Si c'est bien ça, ALWEBER a raison de proposer de supprimer les caractères non imprimables avant de splitter selon l'espace, puis chaque groupe de 3 points selon la virgule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      S := LNode2.NodeValue;
      S := StringReplace(S, #$A, '', [rfReplaceAll]);
      S := StringReplace(S, #9, '', [rfReplaceAll]);
      SplittedPts := SplitString(S, ' ');
      FirstThreePoints := SplitString(SplittedPts[0], ',');

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Citation Envoyé par FlyByck Voir le message
    Bonjour

    La solution String replace a déjà été testée, (voir la dernier phrase du post).
    Elle n'est pas fonctionnelle. Je ne comprend pas pourquoi mais aucun des caractères indésirables sont remplacés alors que la fonction fonctionne normalement sur les caractères entre les quotes.

    C'est idem pour les quotes, je ne peux pas les substituer par un autre caractère
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ArrayPts := StringReplace(SplittedPts[K],'''','$',[rfReplaceAll, rfIgnoreCase]);
    Ok mais l'apostrophe c'est #39 ainsi pas d'histoire de double apostrophes, si en plus on utilise Trim
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ArrayPts := StringReplace(Trim(SplittedPts[K]),#39,'$',[rfReplaceAll, rfIgnoreCase]);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm112.Button2Click(Sender: TObject);
    var L : String;
    begin
    L:=#$A#9#9#9+QuotedStr('3.78919818067865,49.23157613507813,0 ')+
       QuotedStr('3.78919818067865,49.23157613507813,0 ')+#$A#9#9#9;
    Memo1.Lines.Add(Trim(L));
    Memo1.Lines.Add(StringReplace(Trim(L),#39,'$',[rfReplaceAll]));
    end;
    Citation Envoyé par résultat
    $3.78919818067865,49.23157613507813,0 $$3.78919818067865,49.23157613507813,0 $

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 764
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    On voit bien qu'il n'y a pas d'apostrophe dans le XML, ce n'est que le debuggeur qui présente ainsi la chaîne au survol (comme déjà mentionné par tourlourou).

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Ce n'est pas spécifié donc je réponds comme un bourrin en considérant que la chaine récupérée contient ces apostrophes.
    AHMA Trim suffit mais, bon le sujet étant RegEx qui me semble inutile je réponds à la problématique RegEx, je me demande même si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const PATTERN = #39'.*\s'#39;
    ne fonctionnerait pas

    [Edit] après test le PATTERN fonctionne, puisque le match me fourni 1 groupe mais 1 groupe n'est pas le résultat souhaité je m'attendais à 2

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2003
    Messages : 115
    Points : 60
    Points
    60
    Par défaut
    Re bonjour

    La bonne solution est celle-ci
    Citation Envoyé par Andnotor Voir le message
    Tu pourrais aussi passer par Trim.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ArrayPts    := LNode2.NodeValue;
    SplittedPts := SplitString(ArrayPts.Trim([#$A, #$9]));
    Mais l'idéal serait d'avoir un XML correctement formaté. L'indentation du contenu de <coordinates> n'a pas lieu d'être.
    Le XML est créer par Google Earth les caractères ne dépende pas de mon code

    Merci à tous pour votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Difference entre [Simple quote] & [Double quote]
    Par Invité dans le forum SQL
    Réponses: 3
    Dernier message: 24/07/2013, 12h24
  2. Regex: supprimer les simples quotes
    Par RTK45 dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 23/02/2012, 10h03
  3. Résolution macro entre simples quotes
    Par Filippo dans le forum Macro
    Réponses: 8
    Dernier message: 22/04/2010, 15h07
  4. Script shell : afficher le contenu des variables entre simple quote
    Par mualki dans le forum Shell et commandes GNU
    Réponses: 10
    Dernier message: 23/01/2010, 00h14
  5. Réponses: 3
    Dernier message: 20/01/2007, 20h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo