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

Scripts/Batch Discussion :

une Regex multiligne en powershell [PowerShell]


Sujet :

Scripts/Batch

  1. #1
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut une Regex multiligne en powershell
    Bonjour,

    J'ai un fichier de rapport et dans ce fichier un tableau en texte brute.

    J'ai besoin de chercher ce tableau. Pour ce faire, j'utilise des regex.

    Pour trouver la regex, j'utilise notepad++ pour faire mes essaies.

    Dans cette échantillon du fichier texte :

    [...]
    Daughterboard revision number : A0
    Hardware Board Revision Number : 0x01

    Switch Ports Model SW Version SW Image
    ------ ----- ----- ---------- ----------
    * 1 52 WS-C2960S-48FPS-L 12.2(55)SE5 C2960S-UNIVERSALK9-M
    2 52 WS-C2960S-48FPS-L 12.2(55)SE5 C2960S-UNIVERSALK9-M


    Switch 02
    ---------
    Switch Uptime : 2 years, 50 weeks, 2 days, 3 hours, 19 minutes
    Base ethernet MAC Address : 58:97:1E:9C:BA:80
    [...]
    Pour trouver le tableau avec les entêtes "Switch;Ports;Model;SW Version;SW Image", j'utilise cette regex :

    Code regex : Sélectionner tout - Visualiser dans une fenêtre à part
    (?m)^Switch.*Ports.*Model.*SW Version.*(?:(?:\r\n|[\r\n]).+$)*

    Ensuite, j'essai de faire la même chose en Powershell :

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $fileContent = [io.file]::ReadAllText("C:\shver.txt")
    $fileContent | Select-String "(?smi)^Switch.*Ports.*Model.*SW Version.*(?:(?:\r\n|[\r\n]).+$)" -AllMatches | %{ $_.Matches } | %{ $_.Value }

    Sauf que la regex n'arrive pas à s'arrêter à la fin de mon tableau et elle me retourne les lignes jusqu'à la fin du fichier.

    Que faire au niveau de la regex ?

    en vous remerciant d'avance.

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Salut,
    la présence des options m et s n'est-elle pas contradictoire ?

  3. #3
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    salut Laurent,

    dans ce cas present c'est inutile mais dans d'autres cas on peux combiner les modificateur (m) et (s) par exemple

    Code powershell : 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
     
    $a = @'
    line 1
    line 2
    line 3
    '@
     
    $rx1 = [regex]'(?m).*$\n'  #
    $rx2 = [regex]'(?s).*$\n'  #
    $rx3 = [regex]'(?ms).*$\n' # 
     
    "$rx1"
    $rx1.Match($a).value | Write-Host -ForegroundColor Cyan
    "$rx2"
    $rx2.Match($a).value | Write-Host -ForegroundColor DarkCyan
    "$rx3"
    $rx3.Match($a).value | Write-Host -ForegroundColor Green

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sortie:
    (?m).*$\n
    line 1
    
    (?s).*$\n
    
    (?ms).*$\n
    line 1
    line 2
    l'interpretation de $\n

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    'line\ 1\r\nline\ 2\r\nline\ 3'
    |s----------------------------^ FALSE
    |m----------^ TRUE
    |ms--------------------^ TRUE

  4. #4
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    Citation Envoyé par Laurent Dardenne Voir le message
    Salut,
    la présence des options m et s n'est-elle pas contradictoire ?
    A la lecture des article, il semble que oui, après, j'ai utilisé un exemple sur internet...

    Si je les retire, je n'ai plus rien en retour.

  5. #5
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    Citation Envoyé par I'm_HERE Voir le message
    salut Laurent,

    dans ce cas present c'est inutile mais dans d'autres cas on peux combiner les modificateur (m) et (s) par exemple

    Merci pour ces exemples.

    Par exemple si on fait ça :

    Code powershell : 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
    $a = @'
    line 1
    line 2
    line 3
    line 4
     
    line 5
    line 6
    '@
     
    $rx1 = [regex]'(?m).*$\n'  #
    $rx2 = [regex]'(?s).*$\n'  #
    $rx3 = [regex]'(?ms).*$\n' # 
     
    "$rx3"
    $rx3.Match($a).value | Write-Host -ForegroundColor Green

    On a ce retour

    (?ms).*$\n
    line 1
    line 2
    line 3
    line 4

    line 5
    Il ne s'arrête pas au saut de ligne

  6. #6
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Salut Walid,
    je vais regarder ça de plus près, les options portant principalement sur le $, la présence de \n dans tes exemples me laisse perplexe .

    Pour la question d'origine, on connait le début du groupe mais quelle est sa fin ?
    Comment la reconnaitre ?

  7. #7
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    salut,

    généralement on utilise le mode multiline (m) quand on veux traiter un texte ligne par ligne dans ce mode on peux facilement anchrer notre ligne/texte pour savoir si on est au debut ou à la fin d'une lettre ou suite de lettres grâces aux ancres surtout (^$), . Le mode dot-all (s) est généralement utilisé quand on veux traiter le texte en une seul ligne, dans ce mode le point '.' peux même matcher les types differents de retours à la ligne donc les ancres '^$' sont dans ce mode egaux respectivement aux anchres '\a et \z\Z', quand on combine les deux modes c'est généralement quand on veux traiter le texte en une seule ligne et en même temps bénéficier des avantages des ancres surtout ^ et $

    dans cette exemple on veux traiter le texte en mode dot-all c'est à dire que le '.' match TOUT mais en meme temps on veux se positionner au debut de la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $a = @'
    test debut
    debut
    123
    456
    fin
    suite
    '@
    
    $rx3 = [regex]'(?sm)^debut.*?fin' # 
     
    $rx3.Match($a).value| Write-Host -ForegroundColor Green

  8. #8
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Merci.
    C'est effectivement l'usage du mot ligne (multi ou simple) qui peut prêter à confusion :
    Multiline m
    Utilise le mode multiligne, où ^ et $ correspondent au début et à la fin de chaque ligne (plutôt qu'au début et à la fin de la chaîne d'entrée).

    Singleline s
    Utilise le mode à ligne simple, où le point (.) correspond à chaque caractère (y compris \n).
    On peut donc utiliser les deux en même temps. J'ai appris quelque chose

  9. #9
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1

  10. #10
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    Merci pour ces exemple très claire !

    Mais quand la fin est des sauts de ligne, on fait comment ?

    le \r ou \n ne donne pas le résultat attendu.

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $a = @'
    test debut
    debut
    123
    456
    fin
    toto
     
    suite
    '@
     
    $rx3 = [regex]'(?sm)^debut.*?\r\n' # 
     
    $rx3.Match($a).value| Write-Host -ForegroundColor Green

  11. #11
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    salem,

    il faut savoir qu 'en mode Dot-All les retours à la lignes sont ajouté automatiquement
    le pattern que tu as fais ne marche pas comme tu le souhaite car tu lui as demandé une autre chose (et il l'a faite bien)
    le model que tu as utilisé veux dire: quand tu trouve au tout debut d'une ligne les chars D E B U T. tu les bouffes, les commandes suivantes signifient ".*?" t'as le choix ou bien tu t'arrête ou bien commence par bouffé les chars suivant un à un mais l'option 1 est à prendre en compte en priorité. puisque .*? retourne toujours TRUE même si le nombre de chars est 0 donc jusqu'ici il y a un match "Debut". les commandes suivantes \r\n veulent dire: mange ces deux types de retours à la ligne...au final il y a une correspondance dans la chaine à savoir: "Debut\r\n".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
               debut\r\n123\r\n456\r\nfin
              ^    ^   ^
    ^      ---|    |   |
    debut  --------|   |
    .*?    --------|   |
    \r\n   ------------|
    tu as plusieurs options l'une d'elle est:

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $rx3 = [regex]'(?sm)^debut.*?^\s+$'

    dans ce cas tu est sûre que le ligne suivante est vide

    Code powershell : 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
     
    PS C:\> $a = @'
    test debut
    debut
    123
    456
    fin
    toto
     
    suite
    '@
     
    PS C:\> $rx3 = [regex]'(?sm)^debut.*?^\s+$' 
     
    PS C:\> $rx3.Match($a).value| Write-Host -ForegroundColor Green
    debut
    123
    456
    fin
    toto
     
     
    PS C:\>

  12. #12
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    Salut I'm_HERE,

    Merci pour ton retour et tes explications. Vu comme ça, effectivement, dans ma regex, elle ne pouvait que bouffer les sauts de ligne. La subtilité ce présente ici "^\s+$" dans ta solution. Je ne la connaissais pas !

    J'ai réussie à adapter ton exemple à mon besoin et cela fonctionne parfaitement !

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

Discussions similaires

  1. [RegEx] une Regex multiligne
    Par arnaudperfect dans le forum Langage
    Réponses: 2
    Dernier message: 07/09/2018, 01h13
  2. [RegEx] regex sur une chaine multilignes
    Par shinji7800 dans le forum Langage
    Réponses: 6
    Dernier message: 19/03/2017, 08h56
  3. [PowerShell] Inclure une variable Powershell dans une regex
    Par arnaudperfect dans le forum Scripts/Batch
    Réponses: 5
    Dernier message: 15/04/2015, 12h33
  4. [RegEx] spliter par rapport a une regex en récuperant la regex
    Par Khrysby dans le forum Langage
    Réponses: 1
    Dernier message: 10/11/2005, 15h08
  5. [langage] Extraire un block dans une variable multiligne
    Par |DUCATI| DesMo dans le forum Langage
    Réponses: 9
    Dernier message: 11/02/2003, 14h56

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