我有一个可以包含数字、字母和特殊字符的文本,我希望使用正则表达式提取其中的所有数字。
棘手的部分是,任何两个数字之间的字符应该被提取为一个整数。在中间有空格的任何两个数字都应该作为两个单独的数字产生。
示例:ds[44]%6c
应该生成446
,但是2021 ds[44]%6c
应该生成2021
、446
我尝试了下面的Regex
(-?\d+)
这在某种程度上很好,但我不知道如何匹配,直到我看到一个空格,忽略数字之间的字符。
发布于 2022-11-13 05:30:19
我们可以创建一个正则表达式,该表达式捕获一个序列,其中包含至少一个数字,在左边和右边都以零或多个非空白字符括起来。
使用这个使用Java9 Matcher.results()
的正则表达式,我们可以生成Stream
of MatchResult
s,这是一个包含有关匹配组的信息的对象。
唯一剩下的就是提取匹配组,消除非数字字符,并收集结果。
public static final Pattern TEXT_WITH_DIGITS = Pattern.compile("[^\\s]*\\d+[^\\s]*");
public static List<Integer> getInts(String str) {
return TEXT_WITH_DIGITS.matcher(str).results() // Stream<MatchResult>
.map(MatchResult::group) // Stream<String> - extract the matching string
.map(s -> s.replaceAll("\\D+", "")) // remove non-digit characters
.map(Integer::valueOf) // Stream<Integer> - parse the string
.toList();
}
另一个选项是在空格上拆分给定的字符串。为此,我们可以使用Java8 Pattern.splitAsStream()
,它生成的元素流与String.split()
生成的元素流相同。区别在于,Pattern.splitAsStream()
直接从regex引擎创建流,而无需在内存中分配中间数组。
然后,要应用与前面示例相同的转换,只需添加一小部分:当givens字符串以空白开始时,我们需要处理边缘情况。在这种情况下,第一个元素将是空字符串,我们可以使用dropWhile()
丢弃这样的字符串。
public static final Pattern WHITE_SPACES = Pattern.compile("\\s+");
public static List<Integer> getInts(String str) {
return WHITE_SPACES.splitAsStream(str)
.dropWhile(String::isEmpty) // very first element might be empty, and if that's the case it needs to be skipped
.map(s -> s.replaceAll("\\D+", "")) // remove non-digit characters
.map(Integer::valueOf) // Stream<Integer> - parse the string
.toList();
}
main()
public static void main(String[] args) {
System.out.println(getInts("ds[44]%6c"));
System.out.println(getInts("2021 ds[44]%6c"));
}
输出:
[446] // "ds[44]%6c"
[2021, 446] // "2021 ds[44]%6c"
https://stackoverflow.com/questions/74416784
复制相似问题