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;
}
一旦我们为正则表达式定义了 匹配器 ,我们就可以在循环中使用它来 查找 和计算所有匹配项。我们来测试一下:
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;
}
一旦我们在正则表达式上创建了 匹配器 ,我们就可以在循环中使用它来 查找 字符串中的所有整数。我们在每场比赛中调用 group 来获取所有整数。
让我们测试一下 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 :
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");
六,结论
在本文中,我们首先讨论了如何使用正则表达式和 Google Guava 的 CharMatcher 类来计算字符串中的数字。
然后,我们探索使用正则表达式来查找整数和小数。
最后,我们介绍了如何查找其他格式的数字,例如科学记数法和十六进制。
与往常一样,本教程的源代码可以在 GitHub 上找到。