Регулярные выражения Java: часть 7 — Извлечение текста с помощью java.util.Scanner
Здравствуйте, и добро пожаловать обратно. В этой части я покажу вам, как мы можем использовать класс Scanner в пакете java.util для извлечения текста из строки.
Прежде чем углубляться в примеры, давайте обсудим две концепции токенов и разделителей.
В строке есть 2 типа текста: жетоны а также разделители. Токены — это значащие слова, а разделители — это символы, разделяющие токены.
Например, у меня есть строка: Я так сильно тебя люблю.
Итак, в строке:
жетоны: Я, люблю, тебя, так, и сильно
разделители: пробельные символы.
Однако то, что такое токены и разделители, во многом зависит от наших целей. Например, мы можем использовать пробелы в качестве разделителей; или мы можем указать любые символы для работы в качестве разделителей. Почти все методы разделения строк в Java используют пробельный символ в качестве разделителя по умолчанию.
В этом сеансе мы будем использовать класс Scanner для извлечения текста на основе определенных разделителей или шаблона.
Очень часто мы используем класс сканера для получения ввода от пользователей через пользовательский интерфейс консоли, указав ввод System в качестве параметра конструктора.
На самом деле, класс Scanner может использовать источник входных данных как системный ввод, строковую переменную или файл.
Первый метод, который мы можем использовать для разделения строки на токены, — это метод next() в классе Scanner, который использует пробел в качестве разделителя по умолчанию.
Давайте посмотрим код:
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc;
String s = "I love you so much. I want to marry you";
sc = new Scanner(s);
while (sc.hasNext()) {
String token = sc.next();
System.out.println(token);
}
}
}
В приведенном выше коде сначала был создан экземпляр сканера. И вместо того, чтобы передавать объект System.in в конструктор, я передал строковую переменную s, потому что нам нужно было прочитать, а затем манипулировать строкой:
String s = "I love you so much. I want to marry you";
sc = new Scanner(s);
Затем я использовал цикл while для обхода всех токенов в строке. В условии цикла while вызывался метод hasNext() для проверки наличия следующего токена:
while (sc.hasNext())
Метод hasNext() возвращает true, если токенов больше, в противном случае возвращается false, что также указывает на достижение конца строки.
По умолчанию метод hasNext() использует пробелы в качестве разделителя для разделения и навигации между токенами.
Метод hasNext() считывает токен и останавливается, если достигает разделителя. Если метод продолжает вызываться, он считывает следующий токен и останавливается, если достигает другого разделителя. Весь процесс повторяется до тех пор, пока маркер не закончится.
На самом деле метод hasNext() не считывает токены, а просто проверяет, остались ли еще токены.
Фактически считывает и возвращает токены метод next().
String token = sc.next();
Запустим программу и получим вывод:
I
love
you
so
much.
I
want
to
marry
you
Мы получили приведенные выше результаты, потому что, как упоминалось ранее, по умолчанию метод hasNext() использует пробелы в качестве разделителей.
Однако мы можем указать методу hasNext() использовать любые символы в качестве разделителей.
Например, теперь я хочу использовать как пробелы, так и символы точки (.) в качестве разделителей.
Это можно сделать так:
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc;
String s = "I love you so much. I want to marry you";
sc = new Scanner(s);
sc.useDelimiter("[ .]");
while (sc.hasNext()) {
String token = sc.next();
System.out.println(token);
}
}
}
В коде я добавил следующий вызов метода:
sc.useDelimiter("[ .]");
Метод useDelimiter() используется для информирования метода hasNext() о том, что использовать в качестве разделителей. И, как вы можете заметить, я указал символы пробела и точки.
Обратите внимание, что когда мы используем настраиваемые разделители с использоватьразделитель() метод, пробельные символы больше не используются по умолчанию. Поэтому, если вы хотите использовать пробелы в качестве разделителей, вам необходимо явно указать это, как мы только что сделали.
Теперь пришло время запустить программу:
I
love
you
so
much
I
want
to
marry
you
В выводе вы видите пустую строку. Это потому, что мы использовали как пробелы, так и символы точки в качестве разделителей. И было время, когда эти 2 символа стояли рядом друг с другом (между словом много а также я).
Если мы хотим рассматривать 2 (или более) символа разделителя, расположенных рядом друг с другом, как один, нам нужно применить один символ квантификатора следующим образом:
sc.useDelimiter("[ .]+");
Запустите программу еще раз:
I
love
you
so
much
I
want
to
marry
you
И пустая строка была удалена.
Помимо использования определенных символов в качестве разделителя, мы также можем указать регулярное выражение в качестве разделителя.
Предположим, у меня есть следующая строка:
I love you 4 so much. 34 I 23 want to marry you
В строке есть цифры, и я хочу разбить строку на подстроки на основе этих цифр.
Я могу выполнить задачу следующим образом:
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc;
String s = "I love you 4 so much. 34 I 23 want to marry you";
sc = new Scanner(s);
sc.useDelimiter("\\d+");
while (sc.hasNext()) {
String token = sc.next();
System.out.println(token);
}
}
}
Как вы могли заметить, я использую шаблон цифр в качестве параметра в методе useDelimiter():
sc.useDelimiter("\\d+");
Также обратите внимание, что нам нужно использовать знак плюс (+), чтобы, если есть цифры рядом друг с другом, они рассматривались как одна цифра.
Запускаем программу и у нас будет:
I love you
so much.
I
want to marry you
В приведенном выше случае мы также можем сделать обратное, что означает, что мы можем получить все числа: 4, 34 и 23. Это означает, что я буду использовать все символы в качестве разделителей, кроме цифр.
Для достижения поставленной задачи нам достаточно внести небольшое изменение в шаблон:
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc;
String s = "I love you 4 so much. 34 I 23 want to marry you";
sc = new Scanner(s);
sc.useDelimiter("[^\\d]+");
while (sc.hasNext()) {
String token = sc.next();
System.out.println(token);
}
}
}
Как видите, я поставил знак вставки (^) прямо перед \d, и я думаю, вы все еще помните, что знак вставки означает «кроме».
Таким образом, шаблон означает, что в качестве разделителей будут использоваться любые символы, кроме цифр.
Запускаем программу и получаем:
4
34
23
Предыдущая часть
Следующая часть
—
Посещать Learnbyproject.net бесплатно Курсы по регулярным выражениям и другие бесплатные курсы