1. Обзор
Иногда нам нужно найти числовые цифры или полные числа в строках. Мы можем сделать это как с помощью регулярных выражений, так и с помощью определенных библиотечных функций.
В этой статье мы будем использовать регулярные выражения для поиска и извлечения чисел из строк . Мы также рассмотрим некоторые способы подсчета цифр.
2. Подсчет числовых цифр
Начнем с подсчета цифр, найденных в строке.
2.1. Использование регулярных выражений
Мы можем использовать регулярные выражения Java для подсчета количества совпадений с цифрой.
В регулярных выражениях « \d
»
соответствует «любой одиночной цифре» . Давайте используем это выражение для подсчета цифр в строке:
int countDigits(String stringToSearch) {
Pattern digitRegex = Pattern.compile("\\d");
Matcher countEmailMatcher = digitRegex.matcher(stringToSearch);
int count = 0;
while (countEmailMatcher.find()) {
count++;
}
return count;
}
Как только мы определили Matcher
для регулярного выражения, мы можем использовать его в цикле, чтобы найти
и подсчитать все совпадения. Давайте проверим это:
int count = countDigits("64x6xxxxx453xxxxx9xx038x68xxxxxx95786xxx7986");
assertThat(count, equalTo(21));
2.2. Использование Google Guava CharMatcher
Чтобы использовать Guava , нам сначала нужно добавить зависимость Maven:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
Guava предоставляет метод CharMatcher.inRange для подсчета цифр:
int count = CharMatcher.inRange('0', '9')
.countIn("64x6xxxxx453xxxxx9xx038x68xxxxxx95786xxx7986");
assertThat(count, equalTo(21));
3. Поиск чисел
Для подсчета чисел требуются шаблоны, которые охватывают все цифры допустимого числового выражения.
3.1. Поиск целых чисел
Чтобы построить выражение для распознавания целых чисел, мы должны учитывать, что они могут быть положительными или отрицательными и состоять из последовательности из одной или нескольких цифр . Заметим также, что отрицательным целым числам предшествует знак минус.
Таким образом, мы можем найти целые числа, расширив наше регулярное выражение до « -?\d+
». Этот шаблон означает «необязательный знак минус, за которым следует одна или несколько цифр».
Давайте создадим пример метода, который использует это регулярное выражение для поиска целых чисел в строке:
List<String> findIntegers(String stringToSearch) {
Pattern integerPattern = Pattern.compile("-?\\d+");
Matcher matcher = integerPattern.matcher(stringToSearch);
List<String> integerList = new ArrayList<>();
while (matcher.find()) {
integerList.add(matcher.group());
}
return integerList;
}
Как только мы создали Matcher
для регулярного выражения, мы используем его в цикле, чтобы найти
все целые числа в строке. Мы вызываем группу
для каждого совпадения, чтобы получить все целые числа.
Давайте проверим findIntegers
:
List<String> integersFound =
findIntegers("646xxxx4-53xxx34xxxxxxxxx-35x45x9xx3868xxxxxx-95786xxx79-86");
assertThat(integersFound)
.containsExactly("646", "4", "-53", "34", "-35", "45", "9", "3868", "-95786", "79", "-86");
3.2. Нахождение десятичных чисел
Чтобы создать регулярное выражение, которое находит десятичные числа , нам нужно рассмотреть шаблон символов, используемых при их написании.
Если десятичное число отрицательное, оно начинается со знака минус. Затем следует одна или несколько цифр и необязательная дробная часть. Эта дробная часть начинается с десятичной точки, за которой следует другая последовательность из одной или нескольких цифр.
Мы можем определить это с помощью регулярного выражения «-?\d+(\.\d+)?
“:
List<String> findDecimalNums(String stringToSearch) {
Pattern decimalNumPattern = Pattern.compile("-?\\d+(\\.\\d+)?");
Matcher matcher = decimalNumPattern.matcher(stringToSearch);
List<String> decimalNumList = new ArrayList<>();
while (matcher.find()) {
decimalNumList.add(matcher.group());
}
return decimalNumList;
}
Теперь проверим findDecimalNums
:
List<String> decimalNumsFound =
findDecimalNums("x7854.455xxxxxxxxxxxx-3x-553.00x53xxxxxxxxxxxxx3456xxxxxxxx3567.4xxxxx");
assertThat(decimalNumsFound)
.containsExactly("7854.455", "-3", "-553.00", "53", "3456", "3567.4");
4. Преобразование найденных строк в числовые значения
Мы также можем преобразовать найденные числа в их типы Java.
Преобразуем наши целые числа в Long
, используя Stream
mapping :
LongStream integerValuesFound = findIntegers("x7854x455xxxxxxxxxxxx-3xxxxxx34x56")
.stream()
.mapToLong(Long::valueOf);
assertThat(integerValuesFound)
.containsExactly(7854L, 455L, -3L, 34L, 56L);
Далее мы преобразовываем десятичные числа в Double
таким же образом:
DoubleStream decimalNumValuesFound = findDecimalNums("x7854.455xxxxxxxxxxxx-3xxxxxx34.56")
.stream()
.mapToDouble(Double::valueOf);
assertThat(decimalNumValuesFound)
.containsExactly(7854.455, -3.0, 34.56);
5. Поиск других типов чисел
Числа могут быть выражены в других форматах, которые мы можем обнаружить, настроив наши регулярные выражения.
5.1. Научная нотация
Давайте найдем некоторые числа, отформатированные с использованием экспоненциальной записи:
String strToSearch = "xx1.25E-3xxx2e109xxx-70.96E+105xxxx-8.7312E-102xx919.3822e+31xxx";
Matcher matcher = Pattern.compile("-?\\d+(\\.\\d+)?[eE][+-]?\\d+")
.matcher(strToSearch);
// loop over the matcher
assertThat(sciNotationNums)
.containsExactly("1.25E-3", "2e109", "-70.96E+105", "-8.7312E-102", "919.3822e+31");
5.2. шестнадцатеричный
Теперь найдем шестнадцатеричные числа в строке:
String strToSearch = "xaF851Bxxx-3f6Cxx-2Ad9eExx70ae19xxx";
Matcher matcher = Pattern.compile("-?[0-9a-fA-F]+")
.matcher(strToSearch);
// loop over the matcher
assertThat(hexNums)
.containsExactly("aF851B", "-3f6C", "-2Ad9eE", "70ae19");
6. Заключение
В этой статье мы впервые обсудили, как считать цифры в строке с помощью регулярных выражений и класса CharMatcher
из Google Guava.
Затем мы исследовали использование регулярных выражений для поиска целых и десятичных чисел.
Наконец, мы рассмотрели поиск чисел в других форматах, таких как научная запись и шестнадцатеричный формат.
Как всегда, исходный код этого руководства можно найти на GitHub .