Traitement paramètres en ligne de commande par RexExp

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Traitement paramètres en ligne de commande par RexExp

#1

Message par Tlem »

Bonsoir la compagnie.

Je cherche à faire un traitement "complexe" d'une ligne de paramètres envoyée en ligne de commande par un logiciel métier.

L'éditeur donne comme informations :

Code : Tout sélectionner

PROG.EXE –P<Chemin> [-N<Nom>] [-F<Prénom>] [-B<Date de naissance>] [-D<ID patient>] [-G<Sexe>]
Au départ, j'avais pris comme motif : -P(.*) -N(.*) -F(.*) -B(.*) -D(.*) -G(.)
Mais bon, comme certains paramètres sont optionnels, ça ne peux pas fonctionner correctement. ^^

Du coup j'ai voulu prendre le problème différemment et extraire chaque information dans une variable définie.
Et donc pour le nom, je prends ce qu'il y a entre -N et la balise suivante qui peut être : -F, -B, -D ou -G
Tel que :

Code : Tout sélectionner

Local $sParams = "-P\\Serveur\D\Dossier -N LE NOM -FPierre Yves -D1245"
Local $aPinfos, $sName

; Nom
$aPinfos = StringRegExp($sParams, "(?U)-N(.*)-[FBDG]", 1)
If IsArray($aPinfos) Then
	$sName = $aPinfos[0]
EndIf

; Et la suite comme ci-dessus pour les autres variables
Sauf que s'il n'y a pas de balise supplémentaire ("-P\\Serveur\D\Dossier -N LE NOM"), ça ne fonctionne plus.
Si je vire le Ungreedy, c'est la dernière balise du groupe qui est utilisée et du coup il me prend la totalité des paramètres jusqu'à la dernière balise au lieu de s'arrêter à la première trouvée. :cry:

Comment puis-je faire pour extraire tout ce qu'il y a entre -N et la première balise -F ou -B ou -D ou -G ou la fin de la ligne s'il n'y a pas de balise -F, -B, -D ou -G.

Exemples de résultats souhaités pour les lignes de commandes suivantes :

Code : Tout sélectionner

-NLE NOM			; Nom=LE NOM
-NLE NOM -FPierre Yves		; Nom=LE NOM	Prénom=Pierre Yves
-N LE NOM -D1245		; Nom=LE NOM	ID=1245
-N LE NOM -GM			; Nom=LE NOM	Genre=M

Ensuite, j'ai une question subsidiaire. Comme l'éditeur n'est même pas carré dans son propre code, il lui arrive de renvoyer le nom et le prénom sous la forme :

Code : Tout sélectionner

-NLE NOM Pierre Yves
Et donc il me faudrait séparer nom et prénom.
D'après ce que j'ai pu observer, le nom est toujours en majuscule et le prénom est en minuscule sauf la première lettre de chaque prénom.

J'ai utilisé ceci : (.*[[:upper:]] ) ?(.*)
Mais est-ce la meilleur solution ???

Voilà. Je pense avoir donné le maximum d'infos pour aller droit au but. ;)
Merci d'avance à mes chers experts de la RegExp. ^^
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
rgx
Niveau 4
Niveau 4
Messages : 61
Enregistré le : sam. 16 nov. 2019 17:53
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#2

Message par rgx »

Bonjour Tlem,

Pour le début (entre -N et FBDG) ceci peut convenir (y compris pour le double prénom éventuel)
-N(.+)?-[FBDG]
(Vite fait, à vérifier. Pour "ou jusqu'à la fin de la ligne" je regarderai.)

:wink:
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#3

Message par Tlem »

Merci rgx, mais ne fonctionne pas pour le cas N°1 de mes exemples. ;)
J'avais déjà essayé de rajouter le ? avant le groupe, mais non, ça ne fonctionne pas.
J'ai même essayé ?-(F|B|D|G) mais pas mieux.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
rgx
Niveau 4
Niveau 4
Messages : 61
Enregistré le : sam. 16 nov. 2019 17:53
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#4

Message par rgx »

Avec celle-ci tu auras les deux, mais il faudra tester si c'est la première ou deuxième capture qui est non vide.
(à améliorer, car je n'ai pas encore lu le chapitre StringRegExp (y a-t-il une option de "capture alternative" ?), j'utilise la syntaxe générale PCRE)
-N(.+) -[FBDG]|-N(.+)
Ça prend aussi les prénoms avec tiret (-NLE NOM Pierre-Yves)

Je vais chercher aussi pour la suite (j'aime les regex 8) )

Questions:
- Les paramètres (même facultatifs) se présentent-il toujours dans le même ordre ?
- Les paramètres sont toujours séparés par 1 (seul) espace + un tiret ?
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#5

Message par mikell »

Hello
Je manque de temps mais je pense à qqe chose comme ça (pas fait de crash-test...)
L'avantage, c'est que même si les paramètres sont incomplets ou dans le désordre, tu peux toujours (comme ci-dessous par exemple) faire une array 2D dans laquelle les paramètres resteront définis. Les espaces superflus sont éliminés

#Include <Array.au3>

$s = "PROG.EXE -P\\Serveur\D\Dossier -N LE NOM -FJean Pierre-Yves -B Date de naissance  -GSexe -D1245  "

$a = StringRegExp($s, '((?<=\h-)[PNFBDG])\h*(.*?)\h*(?=-(?1)|$)', 3)
;_ArrayDisplay($a)
Local $n = UBound($a), $k = 2, $a2D[Ceiling($n/$k)][$k]
For $i = 0 To $n - 1
    $a2D[Int($i / $k)][Mod($i, $k)] = $a[$i]
Next
_ArrayDisplay($a2D)

Edit

#Include <Array.au3>

$s = "-NLE NOM Pierre Yves"

$a = StringRegExp($s, '-N\h*((?:[[:upper:]]+\h*)+)\h(.*)', 3)
_ArrayDisplay($a)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
rgx
Niveau 4
Niveau 4
Messages : 61
Enregistré le : sam. 16 nov. 2019 17:53
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#6

Message par rgx »

Alternative sans Regex (à condition que les séparateurs soient constants (1 espace et 1 tiret))
  • Simple
  • On met le résultat dans une table de hachage pour réutilisation facile dans le reste du programme.
  • Fonctionne peu importe l'ordre
  • Fonctionne quelque soit le nombre de champs
  • Pas de doublons
$s = "PROG.EXE -P\\Serveur\D\Dossier -N LE NOM -FPierre-Yves -D1245 -B Date de naissance  -GSexe"
   
Local $aParams = StringSplit($s, " -", 1)
Local $mMap[10]

For $i = 3 To $aParams[0]
   $IdMap        = StringLeft    ($aParams[$i], 1)
   $mMap[$IdMap] = StringTrimLeft($aParams[$i], 1)
   ConsoleWrite($IdMap & " - " & $mMap[$IdMap] & @CRLF)
Next
N -  LE NOM
F - Pierre-Yves
D - 1245
B -  Date de naissance
G - Sexe
:wink:

PS. Contrairement à ce qui est écrit dans la doc (Chapitre Langage > Variable > Table), il faut déclarer un nombre d'éléments dans la map ?
Local $mMap[]
Local $mMap[^ ERROR
Error: Variable subscript badly formatted.

:?:
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#7

Message par Tlem »

Bonsoir messieur et merci pour vos retours.
rgx a écrit : ven. 06 déc. 2019 09:12 Avec celle-ci tu auras les deux, mais il faudra tester si c'est la première ou deuxième capture qui est non vide.
(à améliorer, car je n'ai pas encore lu le chapitre StringRegExp (y a-t-il une option de "capture alternative" ?), j'utilise la syntaxe générale PCRE)
-N(.+) -[FBDG]|-N(.+)
Ne fonctionne pas pour "-N LE NOM -FPierre-Yves -D1245 -GM"
rgx a écrit : ven. 06 déc. 2019 09:12 Questions:
- Les paramètres (même facultatifs) se présentent-il toujours dans le même ordre ?
- Les paramètres sont toujours séparés par 1 (seul) espace + un tiret ?
Réponse à la question 1 : Je dirais que oui, mais cela ne change pas grand chose puisque l'on peux avoir -N -F -B -D -G ou seulement -N -F -G ou encore -N -G, etc ...
Réponse à la question 2 : Le séparateur correspond bien à " -#" avec # = à N, F, B, D ou G, mais il peux y avoir un ou plusieurs espaces avant le " -" si le paramètre précédent en contient en fin de chaîne. Si par exemple quelqu'un a rentré le nom de famille avec un espace en plus. ^^


@Michel
Ta RegExp semble fonctionner a moitié, car le paramètre -P ne fonctionne pas.
De plus, cela m'oblige à rajouter une boucle de traitement pour lire le tableau et vérifier chaque paramètre afin de lui attribuer sa variable. Comme je n'ai pas de contrainte d'optimisation, j'aurais préféré rendre cela plus clair en effectuant une RegExp par variable tel que dans l'exemple de ma demande.

@rgx
Votre solution est très sympathique et fonctionne assez bien, toutefois elle comporte une grosse faille : Un utilisateur qui aurait par mégarde saisi un "-" avec un espace avant/après (par exemple : Pierre - Yves).




Pour mes besoins, je pense vraiment que la récupération de chaque paramètre séparément présente le moins de risque pour les cas spécifiques que je n'ai pas encore trouvé. ^^
Et donc je recherche un motif RegExp qui me retourne tout ce qu'il y a entre " -N" et la premier balise trouvé dans la liste : " -F", " -D", " -B", " -G" ou jusqu’à la fin de la ligne si aucune des balises n'est trouvée. Il me suffira d'adapter pour les autres paramètres. :mrgreen:

Bonne soirée.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
rgx
Niveau 4
Niveau 4
Messages : 61
Enregistré le : sam. 16 nov. 2019 17:53
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#8

Message par rgx »

:!: Attention néanmoins, quelque soit la méthode il y a aussi la possibilité de double prénom avec des espaces mal mis et qui peuvent donc faire correspondre à un identificateur (NFBDG) :wink:

Guy -Noël
Annie -Françoise
Anne -Béatrice
Jean -Denis
Anne -Gaëlle

Rien que sur ces 5 lettres, j'en ai trouvé 71 dans un fichier liste de prénoms.
Pour -B et -D on peut vérifier que la suite est bien une valeur numérique, mais pour les autres ?

Un utilisateur qui aurait par mégarde saisi un "-" avec un espace avant/après (par exemple : Pierre - Yves).
Oui, mais on peut envisager un premier passage avec recherche de la chaine " - " et demander confirmation utilisateur ou mettre de côté?
Réponse à la question 1 : Je dirais que oui, mais cela ne change pas grand chose puisque l'on peux avoir -N -F -B -D -G ou seulement -N -F -G ou encore -N -G, etc ...
En fait, si, cela permet d'ajouter un contrôle supplémentaire pour exclure une partie des fausses balises (ci-dessus). Si une balise se présente avant une autre attendue, alors il y a faute.

Dès qu'un programme parait simple... :D

:idea: Il faudrait signaler à l'éditeur du logiciel métier de mettre des balises ouvrantes et fermantes (et autres que des "") ou des identificateurs plus discriminants (ex: -##NOM)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp  

#9

Message par mikell »

pour extraire le nom comme tu demandes, c'est facile
$r = StringRegExp($s, '\h-N\h*(.*?)(?=\h+-[FBDG]|$)', 1)
Msgbox(0,"", $r[0])
mais tu devrais limiter les crash-tests... si comme le signale rgx tu as un prénom type "Jean -Daniel" ça devient ininterprétable :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#10

Message par Tlem »

@rgx
L'éditeur n'utilise pas de guillemets pour ses balises. C'est moi qui les ai écrit pour montrer les délimitations.
J'ai copié dans le premier message les indications données par l'éditeur.

Concernant le risque existant sur nom/prenom composé , au pire je n'aurai qu'une partie du nom mais ça ce limitera à ça. ^^

@Michel
Je teste ça dans la matinée, mais je pense que ça correspond à ce que je recherche.


Edit :
Le motif de Michel semble passer avec brio tous les tests que je lui ai fait passé, même le plus tordu ou dans le nom je rajoute une autre balise " -N" suite à un nom composé mal écrit (genre JEAN -NOEL).
A l'occasion, une explication du motif à la Michel serait intéressante car regex101.com donne les bases mais pas la réflexion de la logique.
Encore merci à vous deux.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#11

Message par mikell »

Oh c'est simple :
\h-N\h* : balise de départ, toujours de la forme "espace+tiret+N+0 ou plus espaces"
ensuite avec (.*?) on ramasse tout jusqu'à tomber (lookahead) sur la séquence \h+-[FBDG] qui dit "1 ou plus espaces+tiret+F ou B ou D ou G"


Par curiosité et pour mon information personnelle, qu'est-ce qui ne marche pas dans mon tout premier regex ? dans mes essais ça ramassait aussi correctement la balise -P et son contenu


Edit
Un petit délire pour le fun :mrgreen:

#Include <Array.au3>

$s = "PROG.EXE -P\\Serveur\D\Dossier -N LE NOM -FJean Pierre-Yves -B Date de naissance  -GSexe -D1245  "

$s = StringRegExpReplace($s, '\h+-([PNFBDG])\h*', @LF & "$1=")
IniWriteSection(@tempdir & "\test.ini", "PROG.EXE", $s, 2)
$a = IniReadSection(@tempdir & "\test.ini", "PROG.EXE")
FileDelete(@tempdir & "\test.ini")
_ArrayDisplay($a, "PROG.EXE")
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#12

Message par Tlem »

En fait, le paramètre -P étant le premier paramètre, il n'y a pas d'espace dans la ligne. C'est pour cela que dans mon test sur regexe101.com ton motif n'avait pas fonctionné. Mais si je rajoute l'espace, effectivement c'est bon. ^^

Petite question supplémentaire. Pour la date de naissance et l'ID, ce sont des paramètres numérique. Du coup si j'adapte ton motif comme ceci \h-D\h*([[:digit:]]+\h*)(?=\h+-[BG]|$) cela semble fonctionner. Peux-tu me confirmer que j'ai bien fait l'adaptation ?

Concernant le petit délire :
Ouais, ça fonctionne aussi (comme la solution de rgx) mais toujours la même réflexion, il suffit d'un petit grain de sable pour tout mettre en l'air.
$s = "PROG.EXE -P\\Serveur\D\Dossier -NMARIE -NOELLE -FJean Pierre-Yves -B31071967 -D1245 -GM"
C'est pour cette raison que je préfère procéder élément par élément, car même avec un grain de sable dans l'engrenage, le script fonctionnera et dans la cas ci-dessus, j'obtiendrais au moins MARIE en nom de famille. ^^

:bisou:
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
rgx
Niveau 4
Niveau 4
Messages : 61
Enregistré le : sam. 16 nov. 2019 17:53
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#13

Message par rgx »

Bonjour,

Déjà limiter le risque d'erreur en considérant que si la ligne de paramètre est générée par un programme, il y a des chances que:
- La séquence soit dans le même ordre PNFBDG (même si certains sont absents) donc désordre = "fausse balise"
- Il ne doit y avoir que 0 ou 1 fois le même séparateur -[PNFBDG] dans une ligne.

À partir de là, une "pré-moulinette" de contrôle avant découpage assure un contrôle de cohérence.

Dans le cas de la regex, on peut aussi forcer celle-ci à vérifier l'ordre des (éventuelles) 6 lettres.

Intéressant sujet à partir d'un truc qui apparaissait simple :D
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#14

Message par mikell »

Tlem a écrit : sam. 07 déc. 2019 14:50Peux-tu me confirmer que j'ai bien fait l'adaptation ?
En gros oui. Je l'aurais écrit comme ça \h-D\h*(\d+)(?=\h+-[BG]|\h*$) parce que 1) \d c'est plus court :mrgreen: et 2) le \h* est inutile, les espaces seront matchés par le lookahead et de toute façon c'est mieux de ne pas les avoir dans le résultat
ça marche, sous-entendu bien sûr que l'ID se trouve avant la date de naissance et le sexe sans autre balise intercalée, et que tu n'as pas un espace pervers qui vient se greffer entre tes chiffres :twisted:
D'ailleurs \h-D\h*(\d+) suffit probablement

Cela dit je suis tout à fait d'accord avec rgx. En principe ton logiciel est cohérent et ne doit pas retourner n'importe quoi
D'ailleurs il serait intéressant de vérifier si par hasard il n'intègrerait pas lui-même une vérification/mise en forme des données qu'on y entre
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#15

Message par Tlem »

Bonsoir et merci pour vos messages.

Concernant l'ordre des paramètres, comme indiqué dans le message #1, l'éditeur donne comme éléments :

Code : Tout sélectionner

PROG.EXE –P<Chemin> [-N<Nom>] [-F<Prénom>] [-B<Date de naissance>] [-D<ID patient>] [-G<Sexe>]
. J'avoue n'avoir jamais joué sur le mélange des paramètres, il faudra que je teste un jour.

Après, pour mes besoins, peu importe, le but est de récupérer ces paramètres qui sont envoyés par un logiciel tiers et de les traiter (peu importe leur nombre).
D'après ce que j'ai pu voir, l'éditeur de PROG.EXE utilise ce système d'envois de paramètres avec un autre de ses logiciels et il n'envoie que -P et -N et ne s'encombre même pas à séparer le nom et le prénom (d’où ma question subsidiaire du message #1).
Maintenant, ce sont les autres éditeurs qui peuvent ne pas envoyer les paramètres à 100% comme demandés. Comme je dois intercepter ces paramètres pour réaliser le lien vers un autre logiciel, il faut que je fasse en sorte de considérer le pire des scénarios afin d'éviter un plantage du script. ^^

Grace à vous j'ai ce que je cherchais. Je vais quand même faire du crash test au cas ou. ;)

Merci à vous.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#16

Message par Tlem »

mikell a écrit : ven. 06 déc. 2019 13:50
$a = StringRegExp($s, '-N\h*((?:[[:upper:]]+\h*)+)\h(.*)', 3)
Bonsoir. Ce motif ne fonctionne plus si le nom est composé ou s'il y a utilisation de caractères accentués étranger.
En cherchant dans mon code, j'ai retrouvé ceci : -N([\p{Lu}- ]+)(?=[\p{Lu} ]) ([\p{L}- ]*?). Je ne vois pas trop à quoi sert (?=[\p{Lu} ]), mais bon.
Je l'ai adapté en ceci : -N\h*([\p{Lu}-' ]+)(?=[\p{Lu} ])\h+([\p{Lt}\p{L}-' ]+)\h+
A première vue cela fonctionne pour ce genre de cas : "LE N'ÔM-COMPOSË Le Prenom" mais pas pour : "LE N'ÔM-COMPOSË Le P'rénôm-Tordü"

Si cela peux aider, dans le cas de cette récupération de données, je peux avoir après le prénom :
Cas N°1 (un ou plusieurs de ces éléments séparés d'un espace):
  • Rien
  • -B31.07.1967
  • -D1254
  • -GM
Cas N°2 (l'un ou l'autre ou les deux éléments séparés d'un espace) :
  • 31.07.1967
  • le texte "N°Dossier"
PS: La date de naissance, le numéro 1254 et le M sont des valeurs d'exemples.

Merci d'avance à celui qui pourrait m'aider.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2272
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#17

Message par jchd »

Pour PCRE \p<propriété> correspond à un caractère Unicode de la propriété indiquée. Unicode utilise des propriété génériques, sur un caractère, comme \pL pour "Letter", \pN pour "Number", \pS pour "Symbol", \pP pour "Punctuation", \pC pour "Control", \pM pour "Modifier", etc. On peut de plus préciser une sous-classe, par exemple \p{Lu} pour "Letter uppercase", \p{Sc} pour "Symbol currency, etc. Il y a aussi le support pour des scripts comme \p{Latin} (alphabets latins), \p{Cyrillic}, etc.

Pour que ces séquences soient reconnues, il faut demander poliment en mettant (*UCP) en tête de patron. UCP = Unicode Character Property.

La séquence \P<propriété> correspond au contraire à l'absence de la propriété : \P{Nd} correspond à tout caractère Unicode qui n'est pas classifié comme un chiffre décimal.

Du fait de l'ampleur du jeu Unicode, il faut réfléchir avant d'employer ces UCP à l'aveuglette. (*UCP) étend la signification de pas mal de séquences habituelles. Ainsi \d qui correspond habituellement à [0-9] s'étend après (*UCP) à tout ce qui est chiffre décimal Unicode. Et il y a beaucoup de positions Unicode qui sont des chiffres décimaux, Unicode c'est vaste !
Par exemple --et ça date déjà de la version 5.1 d'Unicode-- voici à quoi correspondait (*UCP)\pN donc aussi à (*UCP)\d :
{0x000030, 0x000039, 0}, // pure ASCII digits
{0x0000B2, 0x0000B3, 2}, // SUPERSCRIPT 2 TO 3 \_____ how cleverly devised!
{0x0000B9, 0X0000B9, 1}, // SUPERSCRIPT 1 /
{0x000660, 0X000669, 0}, // ARABIC-INDIC DIGITS
{0x0006F0, 0X0006F9, 0}, // EXTENDED ARABIC-INDIC DIGITS
{0x0007C0, 0X0007C9, 0}, // NKO DIGITS
{0x000966, 0X00096F, 0}, // DEVANAGARI DIGITS
{0x0009E6, 0X0009EF, 0}, // BENGALI DIGITS
{0x000A66, 0X000A6F, 0}, // GURMUKHI DIGITS
{0x000AE6, 0X000AEF, 0}, // GUJARATI DIGITS
{0x000B66, 0X000B6F, 0}, // ORIYA DIGITS
{0x000BE6, 0X000BEF, 0}, // TAMIL DIGITS
{0x000C66, 0X000C6F, 0}, // TELUGU DIGITS
{0x000CE6, 0X000CEF, 0}, // KANNADA DIGITS
{0x000D66, 0X000D6F, 0}, // MALAYALAM DIGITS
{0x000E50, 0X000E59, 0}, // THAI DIGITS
{0x000ED0, 0X000ED9, 0}, // LAO DIGITS
{0x000F20, 0X000F29, 0}, // TIBETAN DIGITS
{0x001040, 0X001049, 0}, // MYANMAR DIGITS
{0x001090, 0X001099, 0}, // MYANMAR SHAN DIGITS
{0x0017E0, 0X0017E9, 0}, // KHMER DIGITS
{0x001810, 0X001819, 0}, // MONGOLIAN DIGITS
{0x001946, 0X00194F, 0}, // LIMBU DIGITS
{0x0019D0, 0X0019D9, 0}, // NEW TAI LUE DIGITS
{0x001B50, 0X001B59, 0}, // BALINESE DIGITS
{0x001BB0, 0X001BB9, 0}, // SUNDANESE DIGITS
{0x001C40, 0X001C49, 0}, // LEPCHA DIGITS
{0x001C50, 0X001C59, 0}, // OL CHIKI DIGITS
{0x002070, 0X002070, 0}, // SUPERSCRIPT 0
{0x002074, 0X002079, 4}, // SUPERSCRIPT 4 TO 9
{0x002080, 0X002089, 0}, // SUBSCRIPT DIGITS
{0x002460, 0X002468, 1}, // CIRCLED DIGITS 1 TO 9
{0x0024EA, 0X0024EA, 0}, // CIRCLED DIGIT 0 another sign of careful, clever planning ...
{0x00A620, 0X00A629, 0}, // VAI DIGITS
{0x00A8D0, 0X00A8D9, 0}, // SAURASHTRA DIGITS
{0x00A900, 0X00A909, 0}, // KAYAH LI DIGITS
{0x00AA50, 0X00AA59, 0}, // CHAM DIGITS
{0x00FF10, 0X00FF19, 0}, // FULLWIDTH DIGITS
{0x0104A0, 0X0104A9, 0}, // OSMANYA DIGITS
{0x01D7CE, 0X01D7D7, 0}, // MATHEMATICAL BOLD DIGITS
{0x01D7D8, 0X01D7E1, 0}, // MATHEMATICAL DOUBLE-STRUCK DIGITS
{0x01D7E2, 0X01D7EB, 0}, // MATHEMATICAL SANS-SERIF DIGITS
{0x01D7EC, 0X01D7F5, 0}, // MATHEMATICAL SANS-SERIF BOLD DIGITS
{0x01D7F6, 0X01D7FF, 0}, // MATHEMATICAL MONOSPACE DIGITS

On peut utiliser \p et \P dans une classe de caractères : [\pLu\pLo]

Malheureusement on ne peut pas exprimer facilement "ce qui est un caractère du script grec mais qui n'est pas une majuscule".
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
rgx
Niveau 4
Niveau 4
Messages : 61
Enregistré le : sam. 16 nov. 2019 17:53
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#18

Message par rgx »

Bonjour,

Ceci fonctionne pour les noms avec les accents et les fins de phrases.
(C'est ma première version mais pour laquelle j'avais oublié le lookahead)
$txt = StringRegExp($txt, '(-N(.+?) -[FBDG]|-N(.+))', 3)
À compléter pour le reste. :wink:

Edit: Je pense qu'on peut serrer encore plus avec un masque pour chaque élément et ainsi exclure les faux positifs.
On sait que:
-N<nom> -F<Prenom> -B<Naissance: 8 chiffres JJMMAAAA> -D<id patient: chiffres> -G<Sexe: M ou F>
Donc si on n'a pas les 3 derniers masques (dont deux sont numériques) alors il s'agit d'un nom seul
Si le début est en majuscules, alors on a nom et prénom dans le même champs.
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#19

Message par Tlem »

Bonsoir rgx.
En réalité les choses ne sont pas aussi simple.
Je sais qu'il y aura toujours -P<chemin> et -N<NOM>, mais les autres informations ne sont pas toujours transmises et même dans l'un des cas je n'ai que -P<chemin> -N<NOM> <Prénom>.
Ensuite, concernant les faux positifs créés par une hypothétique seconde balise, cela me semble peu probable bien que possible. Mais je pense pouvoir survivre à un crash de ce type. ^^
Concernant l'ordre des balises, je pense qu'il est peu probable qu'un éditeur s'amuse à mélanger l'ordre suggéré par l'éditeur de PROG.EXE. Là encore je pense que je survivrait. ;)
Par contre je sais que le nom sera toujours en majuscule, le prénom aura la première lettre seulement en majuscule et que dans le nom et prénom, il peux y avoir des caractères accentués ou spéciaux tel ç, l'apostrophe, le trait d'union ou n'importe quel caractère accessible assez directement avec un clavier classique.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
jpascal
Niveau 6
Niveau 6
Messages : 226
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: Traitement paramètres en ligne de commande par RexExp

#20

Message par jpascal »

Désolé d'arriver comme un cheveu sur la soupe mais voici une fonction qui pourrait t'être utile :
If $CmdLine[0] = 0 Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_sTitleApp, "Vous devez spécifier des options de ligne de commande.")

$g_sDate = @MDAY & '/' & @MON & '/' & @YEAR
Global $LINEARGS_MANDATORY[2][2] = [["-p", "prénom"], ["-n", "nom"]]
Global Const $LINEARGS_OPTIONALS[2][3] = [["-d", "date", $g_sDate]]
CmdLineParser()

Func CmdLineParser()
   If StringRegExp($CmdLineRaw, " -h | -help ") Then
      CmdLineHelpMsg()
   EndIf
   For $CPT = 0 To UBound($LINEARGS_MANDATORY) - 1
      $TEST = StringInStr(" " & $CmdLineRaw, " " & $LINEARGS_MANDATORY[$CPT][0] & " ")
      If $TEST = 0 Then
         CmdLineHelpMsg($LINEARGS_MANDATORY[$CPT][0] & " manquant.")
      Else
         For $CPT2 = 1 To $CMDLINE[0]
            If $CMDLINE[$CPT2] = $LINEARGS_MANDATORY[$CPT][0] Then
               If $CPT2 >= $CMDLINE[0] Then
                  CmdLineHelpMsg($LINEARGS_MANDATORY[$CPT][0] & ": argument absent.")
               Else
                  $VALEUR = $CMDLINE[$CPT2 + 1]
                  If StringLeft($VALEUR, 1) = "-" Then
                     CmdLineHelpMsg($LINEARGS_MANDATORY[$CPT][0] & ": argument incorrect:" & $VALEUR)
                  Else
                     $TEST = Assign($LINEARGS_MANDATORY[$CPT][1], $VALEUR, 2)
                     If $TEST = 0 Then
                        CmdLineHelpMsg($LINEARGS_MANDATORY[$CPT][0] & ": valeur ou variable incorrecte :" & $VALEUR)
                     EndIf
                  EndIf
               EndIf
            EndIf
         Next
      EndIf
   Next

   For $CPT = 0 To UBound($LINEARGS_OPTIONALS) - 1
      $TEST = Assign($LINEARGS_OPTIONALS[$CPT][1], $LINEARGS_OPTIONALS[$CPT][2], 2)
      If $TEST = 0 Then
         CmdLineHelpMsg($LINEARGS_OPTIONALS[$CPT][0] & ": Valeur par défaut incorrecte :" & $LINEARGS_OPTIONALS[$CPT][2])
      Else
         For $CPT2 = 1 To $CMDLINE[0]
            If $CMDLINE[$CPT2] = $LINEARGS_OPTIONALS[$CPT][0] Then
               If $CPT2 >= $CMDLINE[0] Then
                  CmdLineHelpMsg($LINEARGS_OPTIONALS[$CPT][0] & ": argument absent.")
               Else
                  $VALEUR = $CMDLINE[$CPT2 + 1]
                  If StringLeft($VALEUR, 1) = "-" Then
                     CmdLineHelpMsg($LINEARGS_OPTIONALS[$CPT][0] & ": argument incorrect:" & $VALEUR)
                  Else
                     $TEST = Assign($LINEARGS_OPTIONALS[$CPT][1], $VALEUR, 2)
                     If $TEST = 0 Then
                        CmdLineHelpMsg($LINEARGS_OPTIONALS[$CPT][0] & ": valeur ou variable incorrecte :" & $VALEUR)
                     EndIf
                  EndIf
               EndIf
            EndIf
         Next
      EndIf
   Next
EndFunc   ;==>CmdLineParser
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Répondre