Tokenizer, extraire un ensemble délimité de lignes

Fermé
softer Messages postés 2 Date d'inscription vendredi 23 novembre 2012 Statut Membre Dernière intervention 23 novembre 2012 - 23 nov. 2012 à 10:23
KX Messages postés 16741 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 30 mai 2024 - 7 déc. 2012 à 14:24
Bonjour,

je suis entrain de faire un programme qui permet de lire un fichier txt, mon programme arrive à lire le fichier, et garde toute les lignes qui on une partie commune le mot "element"
les lignes gardées sont sera donc :

elements
element Nom1
element Nom2
element Nom3
/elements

elements
element Nom4
element Nom5
element Nom6
element Nom7
/elements

elements
element Nom8
element Nom9
/elements

Ma question : je veux extraire à l'aide des tokens, chaque partie délimité par "elements" et "/elements" comme par exemple la partie suivante :

element Nom1
element Nom2
element Nom3

Voici mon programme, il permet d'extraire chaque ligne séparée seulement :

StringTokenizer st = new StringTokenizer(ligneGardee); //lignes au dessus
String token = " ";
String[] TabTemp={null, null, null}; //un vecteur pour stocker les valeurs extraites

while (st.hasMoreTokens()) {
token = st.nextToken();
System.out.println(token);
if (token.startsWith("element")){


TabTemp[0]=token+" "+st.nextToken();


}

Merci de votre aide.
A voir également:

2 réponses

KX Messages postés 16741 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 30 mai 2024 3 016
23 nov. 2012 à 13:52
StringTokenizer c'est du vieux Java, Scanner est plus pratique :

Mon code fait les deux parties de ton traitement, on garde :
* chaque partie délimité par "elements" et "/elements"
* toute les lignes qui on une partie commune le mot "element"

public static List<List<String>> lire(File f) throws FileNotFoundException
{
    List<List<String>> all = new LinkedList<List<String>>();
    List<String> one = null;
    
    Scanner sc = new Scanner(f);
    while (sc.hasNextLine())
    {
        String line = sc.nextLine();
        
        if (one==null) // on cherche un nouveau bloc {"elements","/elements"}
        {
            if (line.equals("elements")) // début d'un nouveau bloc
            {
                one = new LinkedList<String>();
            }
        }
        else // on est dans un bloc {"elements","/elements"}
        {
            if (line.equals("/elements")) // fin du bloc
            {
                all.add(one);
                one = null;
            }
            else if (line.startsWith("element")) // ajout d'une donné au bloc
            {
                one.add(line);
            }
        }
    }
    
    sc.close();
    return all;
}

Remarque : avec tes quelques lignes de contenu voici ce que ça donne :

System.out.println(lire(new File("C:/test.txt")));
// [[element Nom1, element Nom2, element Nom3], [element Nom4, element Nom5, element Nom6, element Nom7], [element Nom8, element Nom9]]
1
softer Messages postés 2 Date d'inscription vendredi 23 novembre 2012 Statut Membre Dernière intervention 23 novembre 2012
23 nov. 2012 à 14:29
Merci bcp !! ça marche, il me reste un seul souci :
je dois enregistrer les blocs en tant que première valeur de ce vecteur
String[] TabTemp={null, null, null}

avec les tokens je fais ça : TabTemp[0]=token+" "+st.nextToken();
mais avec les scanners j'arrive pas à affecter les sorties (bloc) au valeur de ma table temporaire "TabTemp"
0
KX Messages postés 16741 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 30 mai 2024 3 016
23 nov. 2012 à 17:26
Déjà tu vas avoir un problème car TabTamp est de taille 3, alors que tes blocs peuvent être plus grand ou plus petits (dans ton exemple ils sont de tailles 3, 4, et 2).

Mais sinon la conversion d'une liste vers un tableau se fait facilement, par exemple ici je pense que ce serait plutôt à mettre lorsque l'on détecte la fin du bloc :

if (line.equals("/elements")) // fin du bloc
{
    all.add(one);
    String[] tab = one.toArray(new String[one.size()]);
    one = null;
}
0
SVP, comment ajouter le chemin de mon fichier qui est "c:\\filesjava\\read.txt" sur le List<List<String>> lire(File f)
Merci d'avance
0
KX Messages postés 16741 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 30 mai 2024 3 016
6 déc. 2012 à 16:38
Tu veux rajouter tout le contenu de ce fichier avec une liste déjà existante ?

Tu peux simplement faire comme ça :

List<List<String>> list1 = lire(fichier1);
List<List<String>> list2 = lire(fichier2);
list1.addAll(list2);

Mais cette méthode est un peu lourde car list2 sera contenu deux fois en mémoire.
On pourrait plus astucieusement utiliser le fait que les listes utilisées sont des LinkedList pour supprimer les premiers éléments de la deuxième liste afin de la rajouter à la fin de la première :

List<List<String>> list1 = lire(f1);
LinkedList<List<String>> list2 = (LinkedList<List<String>>) lire(f2);

while (!list2.isEmpty())
	list1.add(list2.removeFirst());

Mais l'idéal est encore de modifier légèrement la méthode lire pour en faire plusieurs :

public static List<List<String>> lire(File f) throws FileNotFoundException
{
    return lire(f,new LinkedList<List<String>>());
}

public static List<List<String>> lire(File f, List<List<String>> all) throws FileNotFoundException
{
    List<String> one = null;
    
    // Tout le reste est identique à la méthode "lire" de départ
    // ...
}

public static List<List<String>> lire(File...f) throws FileNotFoundException
{
	List<List<String>> list = new LinkedList<List<String>>();
	for (int i=0; i<f.length; i++)
		list=lire(f[i],list);
	return list;
}

On peut alors faire comme ceci :

List<List<String>> list = lire(f1);
list = lire(f2,list);

Ou directement :

List<List<String>> list = lire(f1,f2);
0
En effet j'aimerai utiliser les outputs de mon programme comme entrée pour ton programme de scanner, mais au niveau de cette ligne :
public static List<List<String>> lire(File f) throws FileNotFoundException
je ne sais pas quoi mettre à la place du "lire(File f )" pour définir définir mes outputs "Objetsave"


voici mon programme et les outputs sont enregistrés dans une table :

public class selection {

public static void main(String[] args) {


FileReader jk;

try {
fis = new FileReader("c:\\filesjava\\read.txt");
BufferedReader in = new BufferedReader(jk);
String i=null;

String save = "";

try {
while((i = in.readLine()) != null)
{

int index = i.indexOf("common");
if(index >0)

sgarder+= i + "|";

Pattern pattern = Pattern.compile("\\|");

String[] tabsave = pattern.split(save);

System.out.println("");

for(int j = 0; j < tabsave.length; j++)
{
String Objetsave = tabsave[j];

System.out.println("Objetsave: " + Objetsave );
}
}

}
0
KX Messages postés 16741 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 30 mai 2024 3 016
7 déc. 2012 à 14:24
Je ne vois pas pourquoi tu veux changer le File f, de toute façon tu en as besoin. En fait c'est tout le reste qu'il faudrait revoir car là c'est bancale, en particulier ton pattern.split(save); alors que save est toujours une chaîne vide ! En l'état ton tableau sera toujours vide aussi...

Il est difficile d'adapter mon code au tien alors que le tien ne fonctionne pas ! En particulier parce que je ne suis pas sûr de ce qu'il devrait faire s'il était programmé correctement...

Je propose ceci, qui pourrait peut-être correspondre au moins en partie, ça te fera une structure de départ pour y apporter les modifications qui conviennent :

public static List<List<String>> lire(File f) throws FileNotFoundException 
{
    Scanner sc = new Scanner(f);
    
    LinkedList<List<String>> liste = new LinkedList<List<String>>();
    
    while (sc.hasNextLine())
    {
        String line = sc.nextLine();
        if (line.contains("common"))
        {
            String[] tab = line.split("\\|")));
            liste.add(Arrays.asList(tab));
        }
    }
    
    sc.close();
    
    return liste;
}
    
public static void main(String[] args) throws FileNotFoundException
{
    List<List<String>> liste = lire(new File("C:/filesjava/read.txt"));
    System.out.println(liste);
}
0