REGEX besoin d'aide - Divers - Programmation
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
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
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 *
Marsh Posté le 06-06-2019 à 15:40:02
yoyo173 a écrit : Bonjour |
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é.
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+,
Marsh Posté le 06-06-2019 à 16:22:15
mechkurt a écrit : Si tu cliques sur son lien https://regex101.com/r/wi6I2z/1 |
Pour approfondir. Il me semblait que "tous les caractères" devait être noté "." . Là, on s'en passe, apparemment.
Marsh Posté le 06-06-2019 à 16:23:49
\([^)]+[0-9]{4}\) fonctionne aussi ... Sans exclure " )" ?
Pourquoi [^)] et pas [^\)] ?
Fuat que je vois tput ça à tête reposée, tout n'est pas clair
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 []. |
yoyo173 a écrit : \([^)]+[0-9]{4}\) fonctionne aussi ... Sans exclure " )" ? |
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 '.'.
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.
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 []. |
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+,
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 --> j'avais mis un espace derrière \)
Chercher 3 chiffres entre parenthèse
\(\d\d\d\) ou \([0-9]{3}\) ne donnent rien. WTF ? Comprends pas où je me plante
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. |
Là encore, à voir avec l'esprit clair, et aiguisé, et incisif, et ..
Marsh Posté le 06-06-2019 à 22:27:43
Exemple de ce que je proposais :
Code :
|
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.
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+,
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.
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