1

I have implemented the logic to extract some value from a string using regex like this.

for(int i = 0; i < fragmentedHeader.length - 1; i++) {
    if(fragmentedHeader[i + 1].contains("ads_management")) {
        Pattern pattern = Pattern.compile("[0-9]{15}");
        Matcher matcher = pattern.matcher(fragmentedHeader[i]);
        while (matcher.find()) {
            catalogIds.add(matcher.group());
        }
    }
}

Its working as expected. I now have to implement this logic using java streams to make it more readable.I just wanted to make it more readable and easy to the eye. I have implement using this but its not working any suggestions.

Pattern pattern = Pattern.compile("[0-9]{15}");
catalogIds = IntStream.range(0, fragmentedHeader.length - 1)
    .filter(index -> fragmentedHeader[index+1].contains("ads_management") && pattern.matcher(fragmentedHeader[index]).find())
    .mapToObj(index -> fragmentedHeader[index])
    .collect(Collectors.toList());

catalogIds = catalogIds.stream()
    .map(header -> pattern.matcher(header).group())
    .collect(Collectors.toList());

The error I am getting is no match found. But is there any way to supply matcher to the next stream

.filter(index -> fragmentedHeader[index+1].contains("ads_management") && pattern.matcher(fragmentedHeader[index]).find())
.mapToObj(index-> pattern.matcher(fragmentedHeader[index]).group())
Xolo12er
  • 68
  • 1
  • 8
  • @user16320675 yes the error i am getting is no match found. But is there any way to supply matcher to the next stream . ` .filter(index -> fragmentedHeader[index+1].contains("ads_management") && pattern.matcher(fragmentedHeader[index]).find()) .mapToObj(index-> pattern.matcher(fragmentedHeader[index]).group())` – Xolo12er Sep 01 '21 at 09:50

1 Answers1

4

You can use the method Matcher.results() to get a stream of match results for each subsequence of the input sequence that matches the pattern. That will also enables you to do the task in one go instead of the intermadiate steps you are doing right now like storing sub-results in a list.

List<String> catalogIds =
IntStream.range(0, fragmentedHeader.length - 1)
        .filter(index -> fragmentedHeader[index+1].contains("ads_management"))
        .mapToObj(index -> fragmentedHeader[index])
        .flatMap(str -> Pattern.compile("[0-9]{15}").matcher(str).results())
        .map(MatchResult::group)
        .collect(Collectors.toList());
Eritrean
  • 15,851
  • 3
  • 22
  • 28
  • 4
    It’s very recommended to move `Pattern.compile("[0-9]{15}")` out of the stream operation, as there is no need to repeat it for every stream element and it’s not a cheap operation. You may even keep the `Pattern` object in a `static final` variable. Further, mind that `Matcher.results()` is a Java 9 method while this question has been tagged with Java 8. Though, tagging with Java 8 when newer versions are ok, seems to be a widespread behavior. [This answer](https://stackoverflow.com/a/28150956/2711488) provides a pure Java 8 solution for getting a stream of matches, in case this is required… – Holger Sep 01 '21 at 11:05