#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