Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
897 connectés 

  FORUM HardWare.fr
  Programmation
  Divers

  REGEX besoin d'aide

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

REGEX besoin d'aide

n°2334712
yoyo173
Posté le 06-06-2019 à 12:40:06  profilanswer
 

Bonjour
 
On m'a demandé de trouver toutes les références auteurs dans des textes. travail long et pénible, je m'intéresse alors aux expressions régulières. Les auteurs étant tous entre parenthèses, avec un date de publication, je cherche:
-tout ce qui est entre 2 parenthèses consécutives
-ET qui se termine par une date.
 
Je tente donc \(.*[0-9]{4}\)  --> Résultat, est sélectionné dans le texte tout ce qui est compris entre la première parenthèse ouverte et la dernière fermée (précédée de 4 chiffres) du paragraphe, avec tout ce qui se trouve entre les deux.
 
Je cherche à faire en sorte de stopper la sélection à la première parenthèse fermée rencontrées sans tout comprendre et, à force d'écrire des machins et des choses je tombe sur cette solution:
\(.*?\) --> Là n'est sélectionné que ce qui se trouve entre deux parenthèses consécutives (bingo) mais impossible d'ajouter alors la date. En effet, cela ne fonctionne que si j'ai ? qui suit mon * . Et je ne comprends pas la syntaxe ou le résultat, le ? n'étant sensé concerner que le caractère qui précède, comment se fait il que j'ai ce résultat ?
 
En gros, comprends rien et besoin d'aide.
 
Merci :)


Message édité par yoyo173 le 06-06-2019 à 12:44:16
mood
Publicité
Posté le 06-06-2019 à 12:40:06  profilanswer
 

n°2334721
e_esprit
Posté le 06-06-2019 à 13:19:40  profilanswer
 

T'utilises quoi comme moteur pour ta regexp ? (outil, langage)
 
Parce que chez moi ça fonctionne très bien avec \(.*?[0-9]{4}\) :  
https://regex101.com/r/snT96h/1
 
Je pense que tu as voulu faire :  \(.*[0-9]{4}?\) mais auquel cas c'est logique que ça ne fonctionne pas, car comme tu le rappelles, le ? ne s'applique qu'à l'expression qui le précède, donc ton [0-9]{4}. Du coup le .* fonctionne en mode "maximum possible".
 
Après, tu peux aussi réécrire avec comme logique "tout ce qui ne contient pas une parenthèse fermante", soit \([^\)]*[0-9]{4}\) :
https://regex101.com/r/wi6I2z/1


---------------
Ce n'est point ma façon de penser qui a fait mon malheur, c'est celle des autres.
n°2334734
yoyo173
Posté le 06-06-2019 à 15:03:45  profilanswer
 

Bonjour
 
Alors, pour le moteur, je n'en sais rien.
J'utilise ces regex avec gedit ou sublimetextx.
 
Ensuite
--  \(.*?[0-9]{4}\) ne fonctionne pas, il y a des "faux positifs" (ex: "(e.g., competence) compared with middle-aged adults suggesting that they may be less likely to be seen as suitable candidates for positions of power (Magee & Galinsky, 2008" )
-- Et je ne comprends pas:
dans \(.*?[0-9]{4}\) , la succession .*? m'est obscure. N'importe quel caratère avec 0, 1 ou plusieurs occurrences mais 0 ou une fois ???
 
 
Par contre \([^\)]*[0-9]{4}\) fonctionne. Mais là encore je ne comprends pas à quelle classe de caractère se réfère * .Je vois bien ce qu'on exclu [^\)] mais pas ce qui est inclu hormis la date.
 
Question subsidiaire, pour comprendre, si je veux rajouter une exclusion, genre pas de virgules non plus, je colle un ^, où ?
 
En tout cas, merci
 

Message cité 1 fois
Message édité par yoyo173 le 06-06-2019 à 15:06:07
n°2334737
mechkurt
Posté le 06-06-2019 à 15:14:06  profilanswer
 

Si tu cliques sur son lien https://regex101.com/r/wi6I2z/1
Tu peux survoler la partie que tu ne comprends pas (et même la modifier pour tester).
[^\)]* veut dire tous les caractères excepté une fermeture de parenthèse (la caractère parenthèse est protégée par un \ sinon ce serait la fin de la capture) zéro ou plusieurs fois.
Tu peux ajouter la virgule après la ) ou avant le \ puisque tous ce qui est compris entre les crochets sera quantifié par le *

Message cité 1 fois
Message édité par mechkurt le 06-06-2019 à 15:14:57

---------------
D3
n°2334740
e_esprit
Posté le 06-06-2019 à 15:40:02  profilanswer
 

yoyo173 a écrit :

Bonjour
 
Alors, pour le moteur, je n'en sais rien.
J'utilise ces regex avec gedit ou sublimetextx.
 
Ensuite
--  \(.*?[0-9]{4}\) ne fonctionne pas, il y a des "faux positifs" (ex: "(e.g., competence) compared with middle-aged adults suggesting that they may be less likely to be seen as suitable candidates for positions of power (Magee & Galinsky, 2008" )
-- Et je ne comprends pas:
dans \(.*?[0-9]{4}\) , la succession .*? m'est obscure. N'importe quel caratère avec 0, 1 ou plusieurs occurrences mais 0 ou une fois ???
 
 
Par contre \([^\)]*[0-9]{4}\) fonctionne. Mais là encore je ne comprends pas à quelle classe de caractère se réfère * .Je vois bien ce qu'on exclu [^\)] mais pas ce qui est inclu hormis la date.
 
Question subsidiaire, pour comprendre, si je veux rajouter une exclusion, genre pas de virgules non plus, je colle un ^, où ?
 
En tout cas, merci
 


Le faux positif est "normal", c'est le problème des regexp, on lui dit de faire le match minimum, mais il évalue de gauche à droite, et tant que ça matche, il continue. et pour lui c'est la chaine mimimal qu'il peut matcher, il va pas chercher à recommencer son match plus loin.
 
C'est pour cela que la seconde solution est plus fiable, puisque tu lui fait stopper dès qu'il se trouve avant une parenthèse fermante si elle n'est pas suivi de 4 chiffres, du coup il va commencer son match à la '(' suivante, et tu as l'effet souhaité.


---------------
Ce n'est point ma façon de penser qui a fait mon malheur, c'est celle des autres.
n°2334750
gilou
Modérateur
Modzilla
Posté le 06-06-2019 à 16:15:52  profilanswer
 

\([^)]+[0-9]{4}\) ça le fait pas? normalement pas besoin de l'escapement dans un [].
 
A+,
 
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2334754
yoyo173
Posté le 06-06-2019 à 16:22:15  profilanswer
 

mechkurt a écrit :

Si tu cliques sur son lien https://regex101.com/r/wi6I2z/1
Tu peux survoler la partie que tu ne comprends pas (et même la modifier pour tester).
[^\)]* veut dire tous les caractères excepté une fermeture de parenthèse (la caractère parenthèse est protégée par un \ sinon ce serait la fin de la capture) zéro ou plusieurs fois.
Tu peux ajouter la virgule après la ) ou avant le \ puisque tous ce qui est compris entre les crochets sera quantifié par le *


 
Pour approfondir. Il me semblait que "tous les caractères" devait être noté "."  . Là, on s'en passe, apparemment.

n°2334755
yoyo173
Posté le 06-06-2019 à 16:23:49  profilanswer
 

\([^)]+[0-9]{4}\) fonctionne aussi :jap: ... Sans exclure " )" ?  
Pourquoi [^)] et pas [^\)] ?
 
Fuat que je vois tput ça à tête reposée, tout n'est pas clair  :cry:

Message cité 1 fois
Message édité par yoyo173 le 06-06-2019 à 16:28:16
n°2334764
e_esprit
Posté le 06-06-2019 à 17:06:12  profilanswer
 

gilou a écrit :

\([^)]+[0-9]{4}\) ça le fait pas? normalement pas besoin de l'escapement dans un [].
 
A+,
 
 


 

yoyo173 a écrit :

\([^)]+[0-9]{4}\) fonctionne aussi :jap: ... Sans exclure " )" ?  
Pourquoi [^)] et pas [^\)] ?
 
Faut que je vois tput ça à tête reposée, tout n'est pas clair  :cry:


Comme le dit Gilou, y a pas besoin d'échapper le ')' (ni le '(' d'ailleurs) quand on est dans une liste ([...]), puisqu'il ne peut pas y avoir de signification "groupe" (ca n'aurait pas de sens de faire un groupe sur certains élément d'une liste uniquement).
Du coup les 2 fonctionnent.
 
Sinon '.' désigne bien tous les caractères. Mais [^abc] désigne tout ce qui n'est pas a, b ou c. Donc [^)] tout ce qui n'est pas la parenthèse fermante. Vu qu'on liste les caractère qu'on ne veut pas, y a pas besoin de dire '.'.
 


---------------
Ce n'est point ma façon de penser qui a fait mon malheur, c'est celle des autres.
n°2334766
MaybeEijOr​Not
but someone at least
Posté le 06-06-2019 à 17:08:23  profilanswer
 

Là je ne peux pas trop tester mais avec le moteur PCRE on peut utiliser le flag U qui permet d'inverser le sens de recherche de la regexp. Et cela permet alors dans le cas de recherche de balises de retenir la réponse avec la chaîne la plus courte.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
mood
Publicité
Posté le 06-06-2019 à 17:08:23  profilanswer
 

n°2334770
gilou
Modérateur
Modzilla
Posté le 06-06-2019 à 17:49:58  profilanswer
 

gilou a écrit :

\([^)]+[0-9]{4}\) ça le fait pas? normalement pas besoin de l'escapement dans un [].
 
A+,
 
 

En fait, il vaut mieux prendre \([^()]+[0-9]{4}\) pour éviter d'en prendre trop avant aussi.
Pour un truc élaboré,  \((\((?>[^()]|(?R))*\)|[^()])+[0-9]{4}\)  devrait se débrouiller en cas de parenthèses à l'intérieur, mais c'est à tester.
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2334795
yoyo173
Posté le 06-06-2019 à 21:11:42  profilanswer
 

Plein de réflexions à faire.
@e_esprit. tes explications sont le bienvenue, merci.
 
Mais pour une autre plus simple
Chercher 3 chiffres entre parenthèse
\(\d\d\d\) ou \([0-9]{3}\) ne donnent rien. WTF ? Comprends pas où je me plante
--> j'avais mis un espace derrière \)


Message édité par yoyo173 le 06-06-2019 à 21:16:36
n°2334796
yoyo173
Posté le 06-06-2019 à 21:13:19  profilanswer
 

MaybeEijOrNot a écrit :

Là je ne peux pas trop tester mais avec le moteur PCRE on peut utiliser le flag U qui permet d'inverser le sens de recherche de la regexp. Et cela permet alors dans le cas de recherche de balises de retenir la réponse avec la chaîne la plus courte.


Ca va faire partie de mon apprentissage, mais pour le coup je verrais ça plus tard.

gilou a écrit :

En fait, il vaut mieux prendre \([^()]+[0-9]{4}\) pour éviter d'en prendre trop avant aussi.
Pour un truc élaboré,  \((\((?>[^()]|(?R))*\)|[^()])+[0-9]{4}\)  devrait se débrouiller en cas de parenthèses à l'intérieur, mais c'est à tester.
 
A+,
 


 
Là encore, à voir avec l'esprit clair, et aiguisé, et incisif, et ..  :)

n°2334797
MaybeEijOr​Not
but someone at least
Posté le 06-06-2019 à 22:27:43  profilanswer
 

Exemple de ce que je proposais :

Code :
  1. /\((.*), [0-9]{4}\)/gmU


https://regex101.com/r/w16LHA/3

 

Ma solution est plus gourmande, mais présente la possibilité de gérer des parenthèses dans les parenthèses sans passer par de la récursion qui va ébouillanter ton cerveau. Cette solution reste perfectible, par exemple ne gère pas :
Bonjour (dixit M.Bonsoir (Auteur9, 1999))
À ce moment là il faut passer sur de la récursion conditionnelle, comme proposé par Gilou.


Message édité par MaybeEijOrNot le 06-06-2019 à 22:45:15

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2334798
gilou
Modérateur
Modzilla
Posté le 06-06-2019 à 22:32:50  profilanswer
 

cf https://www.regular-expressions.info/tutorial.html (une référence) et https://www.rexegg.com/
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2334872
yoyo173
Posté le 08-06-2019 à 16:44:50  profilanswer
 

Ah ben merci.
J'allais vous demander ou trouver des explications de la syntaxe un peu approfondis.


Message édité par yoyo173 le 08-06-2019 à 16:45:04

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Divers

  REGEX besoin d'aide

 

Sujets relatifs
Aide pour une custom deserialization JAVARegex pour nombres
Besoin d'aide pour trouver mon erreurAide vba word choix dans une liste
[AIDE] Highcharts - graphique en fonction d'une var ID et TimeREGEX, ExtracPDF, et dictionnaire
Aide SDL audiobesoin d'aide Shell/bash svp
regex besoin d'aide :-( 
Plus de sujets relatifs à : REGEX besoin d'aide


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR