私は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の近くでメタ文字 '*'がぶら下がる
私の推測では、元のテキストファイルに*
が不足していることが原因です。どうすればそれを回避できますか?
いいえ、問題は*
は正規表現の予約文字であるため、エスケープする必要があります。
String [] separado = line.split("\\*");
*
は「前の式が0個以上」( Pattern
Javadocs を参照)を意味し、前の式を指定していないため、分割式が不正になります。これが、エラーが 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.
}
すると、最初に投稿した解析コードのバージョンは次のようになります(これによりLinkedListに保存され、Hashtableなどのようなものを使用できます)。
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 .....というファイルが検索されます。ここでは、*を唯一の文字として使用しているため、コンパイラは複数の出現を見つけるために文字を探しているため、例外をスローします。