Как разобрать строку текста с двумя отдельными фрагментами данных?

#java #parsing #java.util.scanner

#java #синтаксический анализ #java.util.scanner

Вопрос:

Я новичок в синтаксическом анализе (и новичок в Java), поэтому я просто хочу быть уверенным, что я правильно концептуализирую это.

Я написал программу, которая позволяет пользователю вставлять текст в текстовое поле, затем нажимать кнопку «Проанализировать данные». Эта кнопка анализирует текст для двух фрагментов данных: имени и числа.

Текстовые данные обычно вставляются пользователем в этой форме:

 john 48915
beth 10431
frank 10112
anne 34887
taserface 90090
bill 56448
  

Я использую регулярное выражение «^ d t.* d $» для обнаружения шаблона, и после подтверждения шаблона мой код синтаксического анализа данных выполняет следующее:

 Scanner parser = new Scanner(inputText);
    parser.useDelimiter("\n");
    while (parser.hasNext()) {
        String nextToken = parser.next();
        String name = nextToken.trim();
        // how do I get the number?
  

Вы заметите разделитель n, который анализирует данные с символом новой строки. Это разбивает данные на строки, но не разбивает каждую строку на две отдельные точки данных. Мне нужно захватить и имя, и номер отдельно.

Я считаю, что мне следует использовать разделитель пробела, но я не уверен, следует ли мне делать это в один или два разных шага. Путаница, я полагаю, проистекает из моего ограниченного понимания того, как сканер выполняет свою работу. Но после просмотра документации Java я все еще не совсем уверен.

Текущий вывод:

 john 48915

beth 10431

frank 10112
  

и т.д.

Ожидаемый результат:

 john

48915

beth

10431
  

и т.д.

Должен ли я выполнять два разных цикла синтаксического анализа, или я могу выполнить работу за один проход?

Комментарии:

1. Почему бы просто не использовать next() метод, который уже разделен пробелом?

2. Я бы избавился от parser.useDelimiter("\n"); . Этим вы попадаете впросак.

3. используйте разделитель по умолчанию.

4. символ пробела — это символ пробела. Я удивлен, что вы не проверили это в начале 🙂

5. Существует так много способов скинуть этот cat, и вам следует поэкспериментировать, используя несколько из них, включая чтение в каждой строке через .nextLine() , а затем разделение строки, по сравнению с использованием вложенных объектов Scanner, один для чтения каждой строки из файла, а другой для разбора каждой полученной строки, ….

Ответ №1:

Ваша проблема в том, что вы используете n в качестве разделителя. Это приводит к тому, что входные данные, которые вы передаете вашему сканеру, разделяются только при разрывах строк, а не, как вы ожидаете, также пробелами.

Одно из решений, которое могло бы сработать, — просто удалить следующую строку: parser.useDelimiter("\n");


Решение, которое также будет работать, заключается в следующем:

     try (Scanner parser = new Scanner(inputText)) {
        while (parser.hasNextLine()) {
            String nextLine = parser.nextLine();
            String[] strings = nextLine.split("\s");
            // Here you can use any pattern to split the line
            String name = strings[0];
            String number = strings[1];
            System.out.printf("%s%n%s%n", name, number);
        }
    }
  

Это приводит к следующему выводу:

john
48915
beth
10431
frank
10112
anne
34887
taserface
90090
bill
56448

Решение дает вам больше контроля над строками и тем, как разобрать имя и номер.

Комментарии:

1. Это был точный вывод, к которому я пришел после некоторого возни. Большое спасибо за подтверждение и за то, что уделили время

Ответ №2:

Вот пример реализации для вашего случая, который предлагает больше контроля и гибкости для адаптации к изменению разделителей —

 import java.util.Arrays;

public class StringSplitExample {

     public static void main(String []args){
        String content = "john 48915n"  
                           "beth 10431n"
                           "frank 10112n"
                           "anne 34887n"
                           "taserface 90090n"
                           "bill 56448";

        String[] dataset = content.split("\n|\s");

        for (String value : dataset) {
            System.out.println(value);
        }
     }
}
  

И ниже приведен вывод для приведенного выше фрагмента кода —

 john
48915
beth
10431
frank
10112
anne
34887
taserface
90090
bill
56448
  

Ответ №3:

Вы можете достичь этой функциональности с помощью метода разбиения строк, ниже приведена та же программа и выходные данные, что и вы хотите.

Я думаю, что без пробела пользователь не сможет перейти к следующей строке при заполнении формы.

   public class ParseLineText {
    public static void main(String[] args) {
        String textData = "john 48915 "   
                          "beth 10431 "   
                          "frank 10112 "   
                          "anne 34887 "   
                          "taserface 90090 "   
                          "bill 56448 ";
        String[] data = textData.split("\s");
        for (String text : data) {
            System.out.println(text);
        }
    }
}
Output:
john
48915
beth
10431
frank
10112
anne
34887
taserface
90090
bill
56448