Подтвердить что ты не робот

Ошибка Tokenizing: java.util.regex.PatternSyntaxException, оборванный метасимвол '*'

Я использую split() для tokenize строки, разделенной с помощью *, следуя этому формату:

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

И я получаю это исключение:

Исключение в потоке "main" java.util.regex.PatternSyntaxException: Висячий метасимвол '*' рядом с индексом 0 *

Я предполагаю, что причиной этого является отсутствие * после возраста в исходном текстовом файле. Как мне обойти это?

4b9b3361

Ответ 1

Нет, проблема в том, что * является зарезервированным символом в регулярных выражениях, поэтому вам нужно его избежать.

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

* означает "ноль или более предыдущего выражения" (см. Pattern Javadocs), и вы не давали это любое предыдущее выражение, делающее ваше разделенное выражение незаконным. Вот почему ошибка была PatternSyntaxException.

Ответ 2

У меня была аналогичная проблема с regex = "?". Это происходит для всех специальных символов, которые имеют некоторое значение в регулярном выражении. Поэтому вам нужно иметь "\\" в качестве префикса для вашего регулярного выражения.

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

Ответ 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, вы можете использовать что-то еще, как 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();
}

Ответ 4

Это потому, что * используется как метасимвол, чтобы обозначить одно или несколько случаев предыдущего символа. Так что, если я напишу M *, тогда он будет искать файлы MMMMMM.....! Здесь вы используете * в качестве единственного символа, поэтому компилятор ищет символ для поиска нескольких вхождений, поэтому он генерирует исключение.:)