10
votes

Regex pour scinder les chaînes de coordonnées imbriquées

J'ai une chaîne de format "[(1, 2), (2, 3), (3, 4)]" , avec un nombre arbitraire d'éléments. J'essaie de la diviser sur les virgules séparant les coordonnées, c'est-à-dire pour récupérer (1, 2) , (2, 3) et ( 3, 4) .

Puis-je le faire dans Java Regex? Je suis un noob complet mais espérant que Java Regex est assez puissant pour cela. Si ce n'est pas le cas, pourriez-vous suggérer une alternative?


0 commentaires

6 Réponses :


7
votes

Vous pouvez utiliser String # Split () pour cela. xxx

le (? <= \\)) LOOKEDEWIND POSITIVE signifie qu'il doit être précédé de ) . Le (? = \\ () lookahead positif signifie que cela doit être suivi par (. Le (, \\ s *) signifie qu'il doit être divisé sur le , et tout espace après Ça. Le \\ sont ici simplement pour échapper aux caractères spécifiques à la février.

qui dit, la chaîne particulière est reconnaissable comme résultat de Liste # Tostring () . Êtes-vous sûr que vous faites des choses de bonne manière?)

MISE À JOUR Selon les commentaires, vous pouvez en effet également faire l'inverse et vous débarrasser de chiffres: xxx

ici le \\ d signifie qu'il doit être divisé sur n'importe quel non -Digit (le < code> \\ d signifie chiffre). Le . après signifie qu'il devrait éliminer les correspondances vierges après les chiffres. je Il faut cependant admettre que je ne suis pas sûr comment éliminer les matchs vierges avant les chiffres. Je ne suis pas encore un gourou de regex formé. Hey, Bart K, pouvez-vous le faire mieux?

Après tout, il est finalement préférable d'utiliser un parseur pour cela. voir Huberts Répondez à ce sujet .


10 commentaires

Il y a aussi des virgules dans les substrings ... vous pouvez string.split ("),"); , et après cela pour ramener le ) .


Oups, n'a pas remarqué que la réponse mise à jour.


Bien taché! J'essaie de reproduire une liste de coordonnées de, Ahem, une liste efficacement.


@Beau, et vous n'avez plus aucune référence à cette liste? Il est un peu fragile de le créer à partir de la sortie d'un tostring () retour ...


@Bart si seulement! Je suis à la recherche de chaînes représentant une série de mouvements d'un jeu via un service Web. Strong typing ftw!


@Beau, je vois maintenant ce dont vous avez besoin. J'ai ajouté quelques lignes supplémentaires pour obtenir les coordonnées.


Grands trucs. Cela m'a tenté de gâcher avec des expressions de regex et je suis venu avec \ (0-9], [0-9] \) pour ne rien inclure de rien qui a la forme de coordonnées. Il serait agréable de le faire travailler avec une surveillance de surveillance négative comme expliqué dans ce lien: Stackoverflow.com/Questtions/406230/...


Whau, je ne savais pas que vous pourriez faire que avec une expression régulière! Je suppose que j'ai besoin de chercher "maîtriser des expressions régulières" de l'étagère et lisez sur ce genre de choses :)


Cela étant dit, dans le cas particulier des coordonnées d'analyse, je recommanderais la solution plus simple / compréhensible de ma réponse ou de la solution Scanner suggérée par HUBERT.


Oui, ce genre de cordes est après tout mieux être analysé / togmenté.



1
votes

Y aura-t-il toujours 3 groupes de coordonnées qui doivent être analysées?

Vous pouvez essayer:

\ [(\ (\ d, \ d \)), (\ (\ d, \ d \)), (\ (\ d, \ d \)) \] < / p>


1 commentaires

Pas nécessairement! Je vais éditer la question; acclamations sur la réponse rapide. Je suppose que certains? * + Quantifiers feront le tour de là?



3
votes

Si vous n'avez pas besoin d'expression de valider la syntaxe autour de em> les coordonnées, cela devrait faire:

import java.util.regex.*;

public class Test {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(\\d+),\\s(\\d+)");
        Matcher matcher = pattern.matcher("[(1, 2), (2, 3), (3, 4)]");

        while (matcher.find()) {
            int x = Integer.parseInt(matcher.group(1));
            int y = Integer.parseInt(matcher.group(2));
            System.out.printf("x=%d, y=%d\n", x, y);
        }
    }
}


6 commentaires

Tout ce que je reçois sont les crochets! : /


J'ai ajouté un échantillon de code Java montrant comment utiliser le regex. Est-ce que cela échoue aussi?


INTEGER.PARSE (...) Ne fonctionne pas: c'est integer.parseint (...) . J'ai pris la liberté pour le modifier et poster un exemple de travail de votre extrait.


La regex renvoie "), (" s et "(" s et ")" S; J'utilise string.split (), dois-je utiliser le matcheur et utiliser des groupes à la place?


@Beau, essayez de compiler et d'exécuter la classe de test: vous verrez que cela fonctionne.


@Beau: la regex que j'ai affichée correspondra aux coordonnées réelles, alors l'utiliser avec string.split () vous donnera beaucoup de ), ( correspondance. Le code L'échantillon dans ma réponse devrait cependant vous guider sur votre chemin, cependant.



0
votes

dans Regexes, vous pouvez diviser sur (? qui utilise POSITIVE STRAND> LOETFEHIND :

string[] subs = str.replaceAll("\[","").replaceAll("\]","").split("(?<=\)),");


2 commentaires

Votre regex produit (1 , 2), (2 , 3), (3 et 4) ON Exemple?


Le "(? <= \\\)), \\ s *" serait plus agréable car il couvre également les espaces. Dans Java Regex vous corde par la manière dont vous avez besoin de double-échapper à la \.



1
votes

Si vous utilisez Regex, vous obtiendrez des rapports d'erreur moche et les choses seront exponentiellement plus compliquées si vos exigences changent (par exemple, si vous devez analyser les ensembles de différents supports carrés en différents groupes).

Je vous recommande d'écrire l'analyseur à la main, c'est comme 10 lignes de code et ne devrait pas être très fragile. Suivez tout ce que vous faites, des parens ouverts, des parens fermés, des accolades ouvertes et des accolades fermées. C'est comme une instruction de commutation avec 5 options (et une valeur par défaut), vraiment pas si mal. P>

Pour une approche minimale, des parens ouverts et des accolades ouvertes peuvent être ignorés, il n'y a donc que 3 cas. p>


Ce serait le minimum de l'ours. p> xxx pré>

Ce n'est pas mieux qu'une solution à base de regex minimale sauf qu'il sera beaucoup plus facile de maintenir et améliorer. (Ajoutez une vérification des erreurs, ajoutez une pile pour une correspondance de paren et carré et de la vérification des virgules mal placées et une autre syntaxe non valide) P>

comme exemple d'extensibilité, si vous deviez placer différents ensembles de crochets carrés groupes délimités dans différents ensembles de sortie, l'addition est alors aussi simple que: p>

    // When we close the square bracket, start a new output group.
    else if(token.equals("]"))
        output.startNewGroup();


2 commentaires

... vous êtes peut-être sur quelque chose ici ... une chance que vous puissiez maigrir du code?


Cela ressemble à l'approche axée sur l'événement SAX utilise pour analyser XML. Je suppose que vous devrez passer par le caractère de texte par caractère et construire une série d'algorithmes pour détecter divers modèles.



9
votes

de java 5 xxx

EDIT: Nous ne savons pas combien de coordonnées sont transmises dans la chaîne coordonnées .


4 commentaires

Belle solution! Et si vous remplacez coordonnées avec java.awt.point il compile telle qu'elle est.


Faites attention aux valeurs négatives!


@notnoop: vrai et aussi étrange qu'il semble que je ne pouvais pas réussir à utiliser un motif de délimitation comme "[^ - 0-9] *" , je devais utiliser quelque chose de moins trivial comme "[^ 0-9] * [(),] \\ s *" . Je suis sur Sun JDk6.


J'aime cela! Cependant, comme je l'ai demandé la regex, je choisirai la meilleure réponse de regex comme le correct pour le bien des personnes ayant une question similaire;) 1 Internet pour vous