Nozalys Posté(e) le 9 janvier 2019 Partager Posté(e) le 9 janvier 2019 Bonjour, Je bloque sur une regex un peu particulière : Voici une chaine de caractère type : " -59.99 -46.54 -25.59 -25.09 -25.51 -48.25 -48.06 -48.06 -48.34 -47.07" Et voici la regexp que j'ai pour la détecter : "(([\s]{1}[0-9\.-]+)+)". Cela fonctionne correctement, mais ça ne me retourne que 2 groupes de capture. Le premier contient toute la chaîne en entrée, le second ne contient que le dernier bloc de valeur " -47.07". Je voudrais que le pattern puisse générer 10 groupes contenant les 10 valeurs. Seulement dans l'exemple ici c'est 10, mais ça peut varier. Comment faire, via expression régulière pour capturer dynamiquement le bon nombre de groupe sans créer un pattern en dur avec la répétition du même motif 10 fois ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
ecatomb Posté(e) le 9 janvier 2019 Partager Posté(e) le 9 janvier 2019 Remplacer les espaces par des retours à la ligne puis utiliser l’expression régulière ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Nozalys Posté(e) le 9 janvier 2019 Auteur Partager Posté(e) le 9 janvier 2019 Oui ça fonctionnerait en effet, tout comme (encore plus simple) un bête stringsplit(" "). Mais l'inconvénient de ces 2 solutions est que cela implique de faire soi-même une boucle for. Non pas que c'est un problème, amis il me semble, à la lecture de cet article qu'on peut déjà gérer ça via la syntaxe regexp. Lien vers le commentaire Partager sur d’autres sites More sharing options...
brice.wernet Posté(e) le 9 janvier 2019 Partager Posté(e) le 9 janvier 2019 Juste une remarque rapide en lisant la regex: me "-" est réservé donc tu dois l'échapper (\-). Je le rendrait aussi optionnel et toujours devant les chiffres. [0-9\.-]+ devient \-?[0-9\.]+ Exemple (non vérifié): (([\s]{1}\-?[0-9\.]+)+) Attention [0-9\.]+ capture encore quelque chose comme 12.34.56 Il faudrait bien découper (en séparant les nombre entiers des décimaux) [0-9]+\.[0-9]*|[0-9]+ Lien vers le commentaire Partager sur d’autres sites More sharing options...
TheKillerOfComputer Posté(e) le 9 janvier 2019 Partager Posté(e) le 9 janvier 2019 Il me semble que les groupes servent à faire une recherche de précision sur un ensemble large en se référant à un groupe détecté auparavant. Du coup, c'est pour quel cadre ? Récupérer chaque "groupe" pour les stocker en variable ? Car pour ça, il y a déjà des fonctions dans les langages. preg_match_all() en PHP ou Matches() en C# par exemple. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Nozalys Posté(e) le 10 janvier 2019 Auteur Partager Posté(e) le 10 janvier 2019 L'objectif est en effet de récupérer chaque groupe afin de reconstruire un tableau de valeur décimales. Le langage, c'est du Java. Pour le moment je n'utilise la regexp que pour sélectionner les lignes intéressantes dans mon flux ASCII d'entrée, ensuite je fais un split() sur les espaces, et un simple parseDouble sur les valeurs du tableau du split : // Parse answer Pattern p2 = Pattern.compile("(([\\s]?[0-9\\.-]+)+)"); String[] answerLines = res.split("\r\n"); int sliceCount = 839; double[][] sliceMatrix = new double[84][10]; int rowMatrix = 0; for(String line : answerLines) { if(!line.startsWith(" ")) continue; Matcher m2 = p2.matcher(line); if(m2.matches()) { String[] values = m2.group(1).substring(1).split(" "); for(int aa = 0; aa < values.length; aa++) { sliceMatrix[rowMatrix][aa] = Double.parseDouble(values[aa]); } rowMatrix++; } } Ça fonctionne très bien évidement, c'est le B-A-BA. Seulement, à la lecture des différents tutoriaux présents sur le site que j'ai cité plus haut, j'ai cru comprendre qu'il y avait la possibilité d'arriver au même résultat directement via la syntaxe regexp, sans split derrière. C'est donc cette méthode élégante que je cherche à comprendre et à utiliser. C'est de l'enrichissement de culture plus que du besoin, puisque j'ai déjà une solution fonctionnelle. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sheepux Posté(e) le 10 janvier 2019 Partager Posté(e) le 10 janvier 2019 Je pense que ton problème c'est le greedy matching (([\s]-[\d\.]+)+?) Je me suis permis d'enlever le - du groupe remarque le ? après le +, cela permet d'avoir une limitation au plus petit pattern qui match. Sinon il prend le plus grand pattern qui est … toute la chaine et donc ne génère qu'un groupe. On passe alors du greedy au lazzy https://regex101.com/r/1RA98S/2 Edit: enfin… ca c'était pour répondre à ta regexp initiale Car sinon le group spliting est juste via le pattern matc -[\d\.]+ https://regex101.com/r/1RA98S/3 ou plus sexy -[\d]+(\.[\d]+) https://regex101.com/r/1RA98S/4 Et le plus performant sera certainement un simple split sur les espaces sans regexp car attention, les regexp ca a l'air magique car ca peut tout faire en 1 seule instruction mais c'est une opération couteuse. Edit2: histoire de décrasser mon java: import java.util.regex.Matcher; import java.util.regex.Pattern; public class HelloWorld{ public static void main(String args[]) { Matcher m = Pattern.compile("-[\\d]+(\\.[\\d]+)") .matcher( " -59.99 -46.54 -25.59 -25.09 -25.51 -48.25 -48.06 -48.06 -48.34 -47.07"); while (m.find()) { System.out.println(m.group()); } } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
Nozalys Posté(e) le 11 janvier 2019 Auteur Partager Posté(e) le 11 janvier 2019 Super cette réponse claire ! En prime je ne connaissait pas regex101.com, je rajoute ça à mes liens d'outils 🙂. Je vais me renseigner un peu sur les notions de greedy/lazy matching. Merci ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sheepux Posté(e) le 11 janvier 2019 Partager Posté(e) le 11 janvier 2019 Passe ce WE sur le discord NXI je pourrai t'expliquer. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Chocobidou Posté(e) le 11 janvier 2019 Partager Posté(e) le 11 janvier 2019 Quelle version de java ? car avec Java 8, il y a les streams ... ( mais j'ai un peu de mal avec l'énoncé au niveau de "10 groupes contenant les 10 valeurs", je ne sais pas si ça correspond à 100% ) exemple: String toto= " -59.99 -46.54 -25.59 -25.09 -25.51 -48.25 -48.06 -48.06 -48.34 -47.07"; List<String> lst = Arrays.asList(toto.split(" ")).stream().map(p-> StringUtils.trim(p)).collect(Collectors.toList()) ; tu peux rajouter un cast en Double si souhaite avoir une type nombre Lien vers le commentaire Partager sur d’autres sites More sharing options...
Nozalys Posté(e) le 12 janvier 2019 Auteur Partager Posté(e) le 12 janvier 2019 On 11/01/2019 at 15:03, Sheepux a écrit : Passe ce WE sur le discord NXI je pourrai t'expliquer. Merci beaucoup pour l'invitation mais tous ces outils de messagerie web audio/vidéo, c'est pas ma tasse de thé... On 11/01/2019 at 15:37, Chocobidou a écrit : car avec Java 8, il y a les streams ... Oui en effet, j'utilise pas mal les streams sur les opérations de listes ou de tableaux, mais ça fait toujours intervenir le string.split(), et je souhaitais surtout apprendre l'utilisation de la regexp correcte. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.