2010-05-03 110 views
67

我想要做的是讀取一個.java文件,並挑出所有的標識符並將它們存儲在列表中。我的問題是與.split()方法。如果以這種方式運行此代碼,您將獲得ArrayOutOfBounds,但是如果將分隔符從「。」更改。到其他任何東西,代碼的作品。但我需要用「。」解析的行。那麼還有另一種方法可以實現這一目標嗎?如何使用「。」作爲java中的String.split()的分隔符

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; 
    } 
} 

回答

147

String.split需要一個正則表達式,'。'對正則表達式有特殊的含義。

你(可能)想是這樣的:

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

有些人似乎遇到了麻煩這項工作,所以這裏是你可以用它來驗證正確的行爲的一些運行的代碼。

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

這並沒有爲我工作... line.split(Pattern.quote() 「」);做了 – AutoMEta 2014-06-12 11:15:52

+2

@AutoMEta,你肯定錯了什麼,或者誤解了你得到的結果。正則表達式''\\。「'對於匹配一個滿站是正確的。 「Pattern.quote(」)。「)從@prunge回答這個問題也是一個很好的通用解決方案,可以包含任何不需要的正則表達式元字符 – msandiford 2014-06-13 00:28:29

+0

@AutoMeta你是對的,這種方法不再有效,並且總是給出空數組。 – Ishaan 2016-06-18 10:12:22

2

split的參數是一個正則表達式。 「」匹配任何東西,所以你的分隔符是什麼。

4

你試過逃脫點嗎?像這樣:

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

5

分裂的參數是一個正則表達式。句點是一個正則表達式元字符,它匹配任何內容,因此line中的每個字符都被認爲是分割字符,並被丟棄,並且它們之間的所有空字符串都被拋出(因爲它們是空字符串)。結果是你什麼都沒有了。

如果您避開了這段時間(通過在它之前添加一個轉義反斜槓),那麼您可以匹配文字週期。 (line.split("\\.")

0

您可能會感興趣的課程StringTokenizer。但是,java文檔建議您使用.split方法,因爲StringTokenizer是一個遺留類。

1

如果性能問題,您應該考慮使用StringTokenizer而不是splitStringTokenizersplit快得多,即使它是「傳統」類(但不被棄用)。

37

當一個字符串分隔符分裂,最安全的方法是使用Pattern.quote()方法:

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

如其他答案所述,"\\."分裂是正確的,但quote()將做到這一點逃避你。

+0

用「\\」分割不再起作用,你的和@ AutoMeta的回答是正確的,應該是首選的方式 – Ishaan 2016-06-18 10:13:42

+1

用'「\\。」分割「仍然適用於我的當前版本 – 2016-11-09 23:25:51

2

這是絕對不是這樣做的最好方法,但是,我通過做下面的事情來完成它。

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]); 

輸出,

Image name : my_image 
Image extension : png 
+1

你知道這不是一個好方法,這個問題已經有了一些正確的方法,那麼共享這個「不潔淨」的問題有什麼意義呢?(只是問) – Tom 2016-08-03 21:18:35

+0

我從來不知道爲什麼split不適用於dot,所以,我嘗試了不同的方法,在看到這個答案之後,我認爲自己做的很酷,因爲我在不知道問題的情況下完成了這項工作,我只是添加了這個答案,以表明我們可以用我們所擁有的東西做點什麼,對整個概念有所瞭解。就這樣。 – CLOUGH 2016-08-03 21:48:58

相關問題