トークン化エラー:java.util.regex.patternsyntaxexception、dangling metacharacter '*'
質問
私は使っている split()
分離された文字列をトークン化する *
この形式に従ってください:
name*lastName*ID*school*age
%
name*lastName*ID*school*age
%
name*lastName*ID*school*age
このコードを使用して「entrada.al」という名前のファイルからこれを読んでいます。
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();
}
そして、私はこの例外を取得しています:
スレッドの例外「メイン」java.util.regex.patternsyntaxexception:ダングリングメタ文字 ' *'インデックス0 *
私の推測では、aの欠如です *
元のテキストファイルの年齢後にこれが原因です。どうすればそれを回避できますか?
解決
いいえ、問題はそれです *
Regexesの予約されたキャラクターなので、逃げる必要があります。
String [] separado = line.split("\\*");
*
「以前の式のゼロ以上」を意味します(を参照してください Pattern
Javadocs)、そしてあなたはそれに以前の表現を与えていなかったため、あなたの分割表現を違法にしました。これがエラーがaの理由です PatternSyntaxException
.
他のヒント
同様の問題がありました regex = "?"
. 。それは、正規表現に何らかの意味を持つすべての特殊文字で起こります。だからあなたは持っている必要があります "\\"
正規表現の接頭辞として。
String [] separado = line.split("\\*");
最初の答えはそれをカバーしています。
ラインのどこかで、あなたの情報を別のクラス/構造に保存することを決めるかもしれないと推測しています。その場合、結果が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.
}
次に、最初に投稿した解析コードのバージョンは次のようになります。
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();
}
これは、 *以前の文字の1つ以上の発生を示すためにメタカラクターとして使用されるためです。したがって、m*を書くと、ファイルを探しますmmmmmm .....!ここでは、 *を唯一のキャラクターとして使用しているので、コンパイラは複数の発生を見つけるキャラクターを探しているので、例外をスローします。:)