public final Pattern PATTERN = Pattern.compile("<abc:c\\sabc:name=\"(\\S+)\"\\sabc:type=\"(\\S+)\">");
try (Stream<String> stream = Files.lines(template.getPath())) {
stream.filter(s -> PATTERN.matcher(s).find()).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
The pattern works fine but how can I catch/get my groups? At the moment I get only Strings.
If the pattern you're applying only appears one time for a line, you can map your Stream<String>
into a Stream<Matcher>
, filter the lines that matches the pattern and finally extract the group 1 and 2 by storing them in an array.
try (Stream<String> stream = Files.lines(Paths.get(""))) {
stream.map(PATTERN::matcher)
.filter(Matcher::find)
.map(m -> new String[] { m.group(1), m.group(2) })
.forEach(a -> System.out.println(Arrays.toString(a)));
} catch (IOException e) {
e.printStackTrace();
}
If the pattern appears more than one time, we would need to loop over the Matcher until find()
returns false
. In this case, we could have
try (Stream<String> stream = Files.lines(Paths.get(""))) {
stream.map(PATTERN::matcher)
.flatMap(m -> {
List<String[]> list = new ArrayList<>();
while (m.find()) {
list.add(new String[] { m.group(1), m.group(2) });
}
return list.stream();
})
.forEach(a -> System.out.println(Arrays.toString(a)));
In Java 9, there may be a new method Matcher.results()
to retrieve a Stream<MatchResult>
of the results. We could use it here instead of having 2 separate find
and group
operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With