Aller au contenu

[Résolu] [Java] Scinder une chaîne de caractère


Iry'

Messages recommandés

Bonjour à tous,

Voilà le problème, j'aimerais faire une recherche dans mon programme avec des conditions "négative".

Par exemple l'utilisateur rentre : "Toto est parti -Riri -Tata Rara" (Comment ça mon exemple est bidon? :francais: )

Il faudra donc trouver tous les champs contenant "Toto est parti" (au mot prêt) et Rara mais ne contenant pas Riri et Tata.

Pour ça j'ai essayé de séparer le String reçu avec la commande split().

J'ai donc tenté ceci :

String s = "Toto est parti -Riri -Tata Rara"

String resultat[] = s.split("[\\s]*-[\\S]*[\\s]*");

Je me retrouve donc avec un tableau de taille 3.

Contenant "Toto est parti", "", "Rara".

C'était presque ce que je voulais, mais dans le cas où deux mots précédés d'un "-" se succèdent, il m'ajoute une entrée vide dans le tableau.

Comment procéder pour éviter cela?

Après, il me faudrait récupérer un tableau avec deux entrées contenant, Riri et Tata, mais je n'ai pas réussi à trouver comment mis prendre avec ces satanées expressions régulières.

Bref, pour résumer, à partir de la chaîne "Toto est parti -Riri -Tata Rara", j'aimerais récupérer un tableau de taille 2 contenant "Toto est parti", "Rara" et un autre tableau de taille 2 contenant "Riri", "Tata".

Si vous pouviez m'éclairer (les expressions régulières et moi ça fait deux :D) .

Lien vers le commentaire
Partager sur d’autres sites

Si tu regardes bien, tous les moteurs de recherche obligent à mettre des guillemets autour des chaînes contenant des délimiteurs (généralement des espaces)... Et ce n'est pas pour rien :craint:

Sinon, essaie ça :

Pattern p = Pattern.compile("([^-]+)|(-\\S+)");
Matcher m = p.matcher(s);
while (m.find())
{	
String option = m.group().trim();
if (option.length() == 0) continue;

if (option.charAt(0) == '-')
{	// c'est une option négative			
}
else
{	// c'est une option positive			
}			
}

Ca devrait marcher correctement sur ton exemple, mais pas sur les mots ayant un tiret intégré (ex: globe-trotteur), qui seront décomposés.

Lien vers le commentaire
Partager sur d’autres sites

Merci beaucoup pour ta réponse.

J'ai testé et cela marche impeccablement sauf effectivement dans le cas où il y a un mot composé d'un tiret (mais ce n'est pas trop grave vu les cas d'utilisation).

Mais j'ai finalement été trop vite et ta première remarque est très bonne, car finalement dans mon cas il n'y a pas moyen de faire une recherche du type :

l'expression exacte Toto est parti et contenant Rara, l'utilisateur est obligé d'ajouter une négation.

J'ai donc essayé de modifier ton script pour l'adapter à ta remarque, mais je n'y arrive pas, ayant du mal à comprendre le script de base déjà (il va falloir que je m'y penche sérieusement sur ces expressions régulières).

Puis-je encore solliciter ton aide pour cette adaptation? :transpi:

Lien vers le commentaire
Partager sur d’autres sites

Désolé, c'est vrai que ce n'est pas très clair, je vais essayé de développer ça.

Le code est tout à fait bon par rapport à ce que j'avais donné comme énoncé.

Mais je n'avais pas prévu le cas où l'utilisateur voudrait rechercher deux occurrences qui ne se suivent pas.

En rentrant dans le champ de recherche : occurrence1 occurrence2, le script va prendre ça comme un tout (et c'est d'ailleurs ce que je voulais à la base).

Mais si l'utilisateur veut rechercher dans un champ l'occurrence1 et l'occurrence2 sans qu'ils se suivent forcément, il doit bidouiller en tapant : occurrence1 -o occurrence2.

Dans ce cas, ta première remarque sur le fait que les moteurs de recherche obligent à mettre des guillemets pour une recherche exacte, est très bonne.

Je recherche donc à modifier le script pour qu'il sépare les mots contenu dans des guillemets des autres, bref comme tous les moteurs de recherche.

Prenons cette recherche ci : Hier matin -poire -pomme "j'ai mangé" bon

J'aimerais donc pouvoir récupérer :

Hier

matin

-poire

-pomme

"j'ai mangé"

bon

En espérant avoir été plus clair :transpi:

Lien vers le commentaire
Partager sur d’autres sites

C'est bien ce qu'il me semblait, avec des guillemets c'est tout de suite mieux :)

Bon, essaie ça :

String s = " ... "  //<-- La chaîne à tester

// Listes des options positives et négatives
List<String> positive = new ArrayList<String>();
List<String> negative = new ArrayList<String>();

/* 
La regex qui pique les yeux... On cherche : 
- soit un ensemble de caractères n'étant pas des guillemets, contenus dans des guillemets, et peut-être précédés d'un tiret
- soit un ensemble de caractères contigus n'étant pas des espaces
*/
Pattern p = Pattern.compile("(-?\"[^\"]+\")|(\\S+)");
Matcher m = p.matcher(s);
while (m.find())
{	
String option = m.group().trim();
if (option.length() == 0) continue;

if (option.charAt(0) == '-')
{	
	// On enlève le tiret au début du mot
	negative.add(option.substring(1));		
}
else
{	
	// On enlève les guillemets au début et à la fin du mot
	if (option.charAt(0) == '\"')
	{	option = option.substring(1,option.length()-1);					
	}
	positive.add(option);			
}			
}

Ca va remplir les deux listes "positive" et "negative" avec, respectivement, les expressions normales et celles précédées d'un tiret.

Remarque au passage : ma regex fonctionne aussi pour les expressions du type -"toto tata" (élimination d'une chaîne entre guillemets).

Have fun

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...