2009-05-27 11 views
37

私はこのフォーマット次*で区切られたStringをトークン化するsplit()を使用しています:トークン化エラー:java.util.regex.PatternSyntaxException、ぶら下がりメタキャラクタ「*」

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

私は名前のファイルからこれを読んでいます

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

そして、私はこの例外を取得しています:

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

このコードを使用して "entrada.al"

私の推測では、元のテキストファイル上の年齢の後に*の不足が原因です。どのように私はそれを回避するのですか?

答えて

118

いいえ、問題は*が正規表現では予約文字なので、エスケープする必要があることです。

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

*Pattern Javadocsを参照してください)「前の式のゼロ個以上」を意味し、あなたのスプリット式は違法作り、それを任意の前の式を与えていませんでした。このため、エラーはPatternSyntaxExceptionでした。

3

最初の答えはそれをカバーしています。

私は、どこかでラインを下っていると推測して、あなたの情報を別のクラス/構造体に保存することにします。その場合は、結果をsplit()メソッドの配列に入れたくないでしょう。

あなたはそれを求めていませんでしたが、退屈なので、ここに例があります。

これは、あなたが一人を表すために書き、クラスであるかもしれない:

 

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

その後、あなたはもともと掲示解析コードのバージョンは次のようなものになります。 (これはLinkedListの中でそれらを格納し、あなたは、ハッシュテーブルのような何か他のものなどを使用することができます。)

 

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

*直前の文字の1つの以上の出現箇所を示すためにメタ文字として使用されているので、それはあります。だから私はM *を書くと、ファイルMMMMMMを探します.....!ここでは*を唯一の文字として使用しているため、コンパイラは複数の出現を見つけるために例外をスローします。:)

5

regex = "?"と同様の問題がありました。これは、正規表現で何らかの意味を持つすべての特殊文字に対して起こります。だから"\\"をプレフィックスとしてあなたの正規表現にする必要があります。

String [] separado = line.split("\\*"); 
関連する問題