2

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())
1
  • @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())` Commented Sep 1, 2021 at 9:50

1 Answer 1

5

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());
Sign up to request clarification or add additional context in comments.

1 Comment

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 provides a pure Java 8 solution for getting a stream of matches, in case this is required…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.