2009-05-27 12 views
37

Sto usando split() a tokenize una stringa separata con * seguendo questo formato:Errore creazione di token: java.util.regex.PatternSyntaxException, penzoloni metacarattere '*'

name*lastName*ID*school*age 
% 
name*lastName*ID*school*age 
% 
name*lastName*ID*school*age 

sto leggendo questo da un file chiamato "entrada.al" utilizzando questo codice:

static void leer() { 

    try { 
     String ruta="entrada.al"; 
     File myFile = new File (ruta); 
     FileReader fileReader = new FileReader(myFile); 

     BufferedReader reader = new BufferedReader(fileReader); 

     String line = null; 

     while ((line=reader.readLine())!=null){ 
      if (!(line.equals("%"))){ 
       String [] separado = line.split("*"); //SPLIT CALL 
       names.add(separado[0]); 
       lastNames.add(separado[1]); 
       ids.add(separado[2]); 
       ages.add(separado[3]); 
      } 
     } 

     reader.close(); 
    } 

e sto ottenendo questa eccezione:

Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0 *

La mia ipotesi è che la mancanza di uno * dopo l'età sul file di testo originale sta causando questo. Come faccio ad aggirarlo?

risposta

118

No, il problema è che * è un carattere riservato nelle espressioni regolari, quindi è necessario evitarlo.

String [] separado = line.split("\\*"); 

* significa "zero o più dell'espressione precedente" (vedi la Pattern Javadocs), e non sono stati dandogli qualsiasi espressione precedente, rendendo la vostra espressione divisa illegale. Questo è il motivo per cui l'errore era un PatternSyntaxException.

3

La prima risposta lo copre.

Immagino che da qualche parte lungo la linea tu possa decidere di memorizzare le tue informazioni in una classe/struttura diversa. In questo caso probabilmente non vorresti che i risultati arrivino a un array dal metodo split().

Non l'hai chiesto, ma sono annoiato, quindi ecco un esempio, spero sia utile.

questo potrebbe essere la classe si scrive per rappresentare una sola persona:

 

class Person { 
      public String firstName; 
      public String lastName; 
      public int id; 
      public int age; 

     public Person(String firstName, String lastName, int id, int age) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.id = id; 
     this.age = age; 
     } 
     // Add 'get' and 'set' method if you want to make the attributes private rather than public. 
} 
 

Poi, la versione del codice di analisi è stato originariamente postato sarebbe simile a questa: (Questo li memorizza in un LinkedList, si potrebbe usare qualcosa di diverso come un Hashtable, ecc ..)

 

try 
{ 
    String ruta="entrada.al"; 
    BufferedReader reader = new BufferedReader(new FileReader(ruta)); 

    LinkedList<Person> list = new LinkedList<Person>(); 

    String line = null;   
    while ((line=reader.readLine())!=null) 
    { 
     if (!(line.equals("%"))) 
     { 
      StringTokenizer st = new StringTokenizer(line, "*"); 
      if (st.countTokens() == 4)   
       list.add(new Person(st.nextToken(), st.nextToken(), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken)));   
      else    
       // whatever you want to do to account for an invalid entry 
        // in your file. (not 4 '*' delimiters on a line). Or you 
        // could write the 'if' clause differently to account for it   
     } 
    } 
    reader.close(); 
} 
 
2

è perché * è usato come un metacarattere per indicare uno o più occorrenze di carattere precedente. Quindi se scrivo M * allora cercherà i file MMMMMM .....! Qui stai usando * come unico carattere in modo che il compilatore cerchi il personaggio per trovare più occorrenze, quindi lancia l'eccezione :)

5

Ho avuto un problema simile con regex = "?". Succede per tutti i personaggi speciali che hanno un significato in un'espressione regolare. Quindi devi avere "\\" come prefisso alla tua espressione regolare.

String [] separado = line.split("\\*"); 
Problemi correlati