Regex from + hostname + ()*

Résolu/Fermé
Utilisateur anonyme - 15 juil. 2015 à 17:44
 Utilisateur anonyme - 17 juil. 2015 à 11:08
Bonjour,

j'essaie de construire une regex mais je tombe sur un petit problème :

ce que ma regex doit capturer :
- "from"[espace]
- hostname[espace]
- (un commentaire)[espace] <-- 0 ou plusieurs fois

Exemple : from sender.domainemail.net (this is comment) (this is another comment) (last comment)

Voici comment se construit ma regex à l'heure actuel

/^from ((?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?) (?:\((.*?)\)\s)+/


le problème c'est qu'il me capure que la dernière parenthèse
 $matches = [
 0 => 'from sender.domainemail.net (this is comment) (this is another comment) (last comment)',
 1 => 'sender.domainemail.net',
 2 => 'last comment'
];


Pourriez-vous me donner un coup de main :)

Merci d'avance

5 réponses

miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
16 juil. 2015 à 00:40
Je crois que j'ai mal compris et que tu veux plutôt ça :

Exemple live : https://ideone.com/FFqEkT

<?php

$regexp = "#\((.+?)\)| #";

$data = "from sender.domainemail.net (this is comment) (this is another comment) (last comment)";

$matches = preg_split($regexp, $data, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);

var_dump($matches);
1
Utilisateur anonyme
16 juil. 2015 à 12:07
C'est pas bête :0

Si j'ai bien compris au lieu de faire un preg_match, on fait un preg_split avec comme délimiteurs les (comments) et les espaces. et on spécifie à preg_split de nous retourner ce qu'il capture lorsqu'il fait son split.

C'est génial ! je vais faire mes tests là-dessus, je vous donne des nouvelles ASAP.
0
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
16 juil. 2015 à 23:58
Hello,
j'ai implémenté ça sous une autre forme, les différents use case donnaient une expression complexe à trouver :

Exemple live : https://ideone.com/3SLrPZ

<?php

$data = "from remote.intra.domain.net (sbs-2011.intra.local [0.0.0.0]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mailhost.domain.net (Postfix) with ESMTPS id A2E067029D9 for <john.doe@domain.net>";

function extractComments($data)
{
    $comments      = [];
    $index         = null;
    $parensCounter = 0;

    foreach(str_split($data) as $char)
    {
        if($char == '(' && !isset($index))
        {
            $index = count($comments);
            $comments[$index] = '';
        }
        else if($char == '(')
        {
            $parensCounter++;
            $comments[$index] .= $char;
        }
        else if($char == ')' && $parensCounter != 0)
        {
            $parensCounter--;
            $comments[$index] .= $char;
        }
        else if($char == ')')
        {
            $parensCounter = 0;
            $index = null;
        }
        else if(isset($index))
        {
            $comments[$index] .= $char;
        }
    }

    return $comments;
}

function extractDomain($data)
{
    $matches = [];

    preg_match('#from\s(.+)\s+#U', $data, $matches);

    return $matches[1];
}

var_dump(array_merge([extractDomain($data)], extractComments($data)));
1
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
15 juil. 2015 à 19:43
Hello,

c'est ça que tu veux ?

Exemple live : https://ideone.com/0ENGxC

<?php

$regexp = "#from\s(.+?)\s(.+)#";

$data = "from sender.domainemail.net (this is comment) (this is another comment) (last comment)"; 

$matches = [];

preg_match($regexp, $data, $matches);

var_dump($matches);
0
Rebonjour, merci pour ta réponse tout fonctionne parfaitement !

Mise à part un point, que je n'avais pas précisé dans le poste initial.

En effet il est possible qu'il y aie des parenthèses dans mes parenthèses

Exemple :
from remote.intra.domain.net (sbs-2011.intra.local [0.0.0.0]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mailhost.domain.net (Postfix) with ESMTPS id A2E067029D9 for <john.doe@domain.net>


dans ce cas j'aimerais récupérer using TLSv1 with cipher AES128-SHA (128/128 bits)

Est-ce qu'il y aurait possibilité de compté les parenthèses qui s'ouvrent dans un commentaire et ignoré le même nombre de parenthèses qui se ferme ?

Je vais rechercher de mon côté mais je reste ouvert à tous conseils ou explications

Merci beaucoup

Seezer
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Hello Miramaze,

Je te remercie pour ton aide !!!

Au final j'ai mélangé tes 2 solutions

dans un premier temps :
- j'ai extrait de ma chaîne, tous les commentaires "de premier niveau"

dans un deuxième temps :
j'ai implode mon tableau contenant les commentaires dans une expression régulière (en échappant les caractères spéciaux)

#\(commentaire\)|\(commentaire\)|\(commentaire\)| #


Ce qui me donne le même résultat qu'à la solution #1 mais avec les commentaires de premier niveau

Encore merci !
0