REGEX besoin d'aide

REGEX besoin d'aide - Divers - Programmation

Marsh Posté le 06-06-2019 à 12:40:06    

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
Reply

Marsh Posté le 06-06-2019 à 12:40:06   

Reply

Marsh Posté le 06-06-2019 à 13:19:40    

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.
Reply

Marsh Posté le 06-06-2019 à 15:03:45    

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
Reply

Marsh Posté le 06-06-2019 à 15:14:06    

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
Reply

Marsh Posté le 06-06-2019 à 15:40:02    

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.
Reply

Marsh Posté le 06-06-2019 à 16:15:52    

\([^)]+[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é!  --
Reply

Marsh Posté le 06-06-2019 à 16:22:15    

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.

Reply

Marsh Posté le 06-06-2019 à 16:23:49    

\([^)]+[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
Reply

Marsh Posté le 06-06-2019 à 17:06:12    

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.
Reply

Marsh Posté le 06-06-2019 à 17:08:23    

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.
Reply

Marsh Posté le 06-06-2019 à 17:08:23   

Reply

Marsh Posté le 06-06-2019 à 17:49:58    

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é!  --
Reply

Marsh Posté le 06-06-2019 à 21:11:42    

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
Reply

Marsh Posté le 06-06-2019 à 21:13:19    

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 ..  :)

Reply

Marsh Posté le 06-06-2019 à 22:27:43    

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.
Reply

Marsh Posté le 06-06-2019 à 22:32:50    

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é!  --
Reply

Marsh Posté le 08-06-2019 à 16:44:50    

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
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed