2010-05-03 7 views
67

Quello che sto cercando di fare è leggere un file .java e selezionare tutti gli identificatori e memorizzarli in un elenco. Il mio problema è con il metodo .split(). Se si esegue questo codice così com'è, si otterrà ArrayOutOfBounds, ma se si modifica il delimitatore da "." a qualsiasi altra cosa, il codice funziona. Ma ho bisogno di righe analizzate da "." quindi c'è un altro modo in cui potrei realizzare questo?Come posso usare "." come delimitatore con String.split() in java

import java.io.BufferedReader; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.*; 


public class MyHash { 
    private static String[] reserved = new String[100]; 
    private static List list = new LinkedList(); 
    private static List list2 = new LinkedList(); 

    public static void main (String args[]){ 
     Hashtable hashtable = new Hashtable(997); 
     makeReserved(); 
     readFile(); 
     String line; 
     ListIterator itr = list.listIterator(); 
     int listIndex = 0; 
     while (listIndex < list.size()) { 

      if (itr.hasNext()){ 
       line = itr.next().toString(); 
       //PROBLEM IS HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       String[] words = line.split("."); //CHANGE THIS AND IT WILL WORK 
       System.out.println(words[0]);  //TESTING TO SEE IF IT WORKED 
      } 
      listIndex++; 
     } 
    } 

    public static void readFile() { 
     String text; 
     String[] words; 
     BufferedReader in = null; 
     try { 
      in = new BufferedReader(new FileReader("MyHash.java")); //NAME OF INPUT FILE 


     } catch (FileNotFoundException ex) { 
      Logger.getLogger(MyHash.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     try { 
      while ((text = in.readLine()) != null){ 
       text = text.trim(); 
       words = text.split("\\s+"); 
       for (int i = 0; i < words.length; i++){ 
        list.add(words[i]); 
       } 
       for (int j = 0; j < reserved.length; j++){ 
        if (list.contains(reserved[j])){ 
         list.remove(reserved[j]); 
        } 
       } 


      } 

     } catch (IOException ex) { 
      Logger.getLogger(MyHash.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     try { 
      in.close(); 
     } catch (IOException ex) { 
      Logger.getLogger(MyHash.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public static int keyIt (int x) { 
     int key = x % 997; 
     return key; 
    } 

    public static int horner (String word){ 
     int length = word.length(); 
     char[] letters = new char[length]; 

     for (int i = 0; i < length; i++){ 
      letters[i]=word.charAt(i); 
     } 

     char[] alphabet = new char[26]; 
     String abc = "abcdefghijklmnopqrstuvwxyz"; 

     for (int i = 0; i < 26; i++){ 
      alphabet[i]=abc.charAt(i); 
     } 

     int[] numbers = new int[length]; 
     int place = 0; 
     for (int i = 0; i < length; i++){ 
      for (int j = 0; j < 26; j++){ 
       if (alphabet[j]==letters[i]){ 
        numbers[place]=j+1; 
        place++; 

       } 
      } 
     } 

     int hornered = numbers[0] * 32; 

     for (int i = 1; i < numbers.length; i++){ 

      hornered += numbers[i]; 
      if (i == numbers.length -1){ 
       return hornered; 
      } 
      hornered = hornered % 997; 
      hornered *= 32; 
     } 
     return hornered; 
    } 

    public static String[] makeReserved(){ 
     reserved[0] = "abstract"; 
     reserved[1] = "assert"; 
     reserved[2] = "boolean"; 
     reserved[3] = "break"; 
     reserved[4] = "byte"; 
     reserved[5] = "case"; 
     reserved[6] = "catch"; 
     reserved[7] = "char"; 
     reserved[8] = "class"; 
     reserved[9] = "const"; 
     reserved[10] = "continue"; 
     reserved[11] = "default"; 
     reserved[12] = "do"; 
     reserved[13] = "double"; 
     reserved[14] = "else"; 
     reserved[15] = "enum"; 
     reserved[16] = "extends"; 
     reserved[17] = "false"; 
     reserved[18] = "final"; 
     reserved[19] = "finally"; 
     reserved[20] = "float"; 
     reserved[21] = "for"; 
     reserved[22] = "goto"; 
     reserved[23] = "if"; 
     reserved[24] = "implements"; 
     reserved[25] = "import"; 
     reserved[26] = "instanceof"; 
     reserved[27] = "int"; 
     reserved[28] = "interface"; 
     reserved[29] = "long"; 
     reserved[30] = "native"; 
     reserved[31] = "new"; 
     reserved[32] = "null"; 
     reserved[33] = "package"; 
     reserved[34] = "private"; 
     reserved[35] = "protected"; 
     reserved[36] = "public"; 
     reserved[37] = "return"; 
     reserved[38] = "short"; 
     reserved[39] = "static"; 
     reserved[40] = "strictfp"; 
     reserved[41] = "super"; 
     reserved[42] = "switch"; 
     reserved[43] = "synchronize"; 
     reserved[44] = "this"; 
     reserved[45] = "throw"; 
     reserved[46] = "throws"; 
     reserved[47] = "trasient"; 
     reserved[48] = "true"; 
     reserved[49] = "try"; 
     reserved[50] = "void"; 
     reserved[51] = "volatile"; 
     reserved[52] = "while"; 
     reserved[53] = "="; 
     reserved[54] = "=="; 
     reserved[55] = "!="; 
     reserved[56] = "+"; 
     reserved[57] = "-"; 
     reserved[58] = "*"; 
     reserved[59] = "/"; 
     reserved[60] = "{"; 
     reserved[61] = "}"; 

     return reserved; 
    } 
} 

risposta

147

String.split prende un'espressione regolare e "." ha un significato speciale per le regex.

che (probabilmente) desidera qualcosa di simile:

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

Alcune persone sembrano avere problemi ottenere questo al lavoro, ecco un po 'di codice eseguibile è possibile utilizzare per verificare il comportamento corretto.

import java.util.Arrays; 

public class TestSplit { 
    public static void main(String[] args) { 
    String line = "aa.bb.cc.dd"; 
    String[] words = line.split("\\."); 
    System.out.println(Arrays.toString(words)); 
    // Output is "[aa, bb, cc, dd]" 
    } 
} 
+4

questo non ha funzionato per me ... line.split (Pattern.quote() ""); – AutoMEta

+2

@AutoMEta è necessario aver digitato in modo errato qualcosa o interpretato erroneamente i risultati che si ottengono. La regex '" \\. "' È corretta per la corrispondenza con un punto. Il 'Pattern.quote (".")' risposta da @prunge a questa domanda è anche una buona soluzione generale per tutte le divisioni che potrebbero includere meta caratteri di regex indesiderati – msandiford

+0

@AutoMeta Hai ragione: questo metodo non funziona più e dà sempre array vuoti. – Ishaan

2

L'argomento di divisione è un'espressione regolare. "" corrisponde a qualsiasi cosa in modo che il delimitatore di dividere è qualsiasi cosa.

4

Hai provato a scappare dal punto? in questo modo:

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

5

L'argomento per dividere è un'espressione regolare. Il punto è un metacarattere di espressione regolare che corrisponde a qualsiasi cosa, quindi ogni carattere in line è considerato un carattere di divisione e viene gettato via e tutte le stringhe vuote tra di esse vengono gettate via (perché sono stringhe vuote). Il risultato è che non hai più niente.

Se si scappa il punto (aggiungendo una barra rovesciata di escape prima di esso), è possibile abbinare periodi letterali. (line.split("\\."))

0

Potresti essere interessato alla classe StringTokenizer. Tuttavia, i documenti java consigliano di utilizzare il metodo .split in quanto StringTokenizer è una classe precedente.

1

Se le prestazioni sono un problema, è consigliabile utilizzare StringTokenizer anziché split. StringTokenizer è molto più veloce di split, anche se è una classe "legacy" (ma non deprecata).

37

Quando si divide con un delimitatore letterale di stringa, il modo più sicuro è quello di utilizzare il metodo Pattern.quote():

String[] words = line.split(Pattern.quote(".")); 

Come descritto da altre risposte, la scissione con "\\." è corretto, ma quote() lo farà scappare per voi.

+0

La divisione con "\\" non funziona più La risposta di Your e @ AutoMeta è corretta, dovrebbe essere il modo preferito – Ishaan

+1

La divisione con '" \\. "' Funziona ancora per me con la versione corrente –

2

Questo è sicuramente non il modo migliore per farlo ma, ho ottenuto facendo qualcosa come il seguente.

String imageName = "my_image.png"; 
String replace = imageName.replace('.','~'); 
String[] split = replace.split("~"); 

System.out.println("Image name : " + split[0]); 
System.out.println("Image extension : " + split[1]); 

uscita,

Image name : my_image 
Image extension : png 
+1

Sai che questo non è un buon modo e questa domanda ha già dei modi corretti, quindi qual è il punto nel condividere questo "sporco"? (Chiedendo semplicemente) – Tom

+0

Non ho mai saputo perché split non funziona per punto. Ho provato un approccio diverso, ho pensato che quello che facevo era bello, dopo aver visto queste risposte, perché l'ho fatto senza conoscere il problema, aggiungo questa risposta solo per dimostrare che possiamo fare qualcosa con ciò che abbiamo, anche con spirito la comprensione di tutto il concetto. È tutto. – CLOUGH

Problemi correlati