You can simply concatenate the streams:
String inFileName = "Sample.log";
String outFileName = "Sample_output.log";
try (Stream<String> stream = Files.lines(Paths.get(inFileName))) {
List<String> timeStamp = stream
.flatMap(s -> Stream.concat(quoteRegex1.results(s),
Stream.concat(quoteRegex2.results(s), quoteRegex3.results(s))))
.map(r -> r.group(1))
.collect(Collectors.toList());
timeStamp.forEach(System.out::println);
//Files.write(Paths.get(outFileName), dataSet);
}
but note that this will perform three individual searches through each line, which might not only imply lower performance, but also that the order of the matches within one line will not reflect their actual occurrence. It doesn’t seem to be an issue with your patterns, but individual searches even imply possible overlapping matches.
The PatternStreamer of that linked answer also greedily collects the matches of one string into an ArrayList before creating a stream. A Spliterator based solution like in this answer is preferable.
Since numerical group references preclude just combining the patterns in a (pattern1|pattern2|pattern3) manner, a true streaming over matches of multiple different patterns will be a bit more elaborated:
public final class MultiPatternSpliterator
extends Spliterators.AbstractSpliterator<MatchResult> {
public static Stream<MatchResult> matches(String input, String... patterns) {
return matches(input, Arrays.stream(patterns)
.map(Pattern::compile).toArray(Pattern[]::new));
}
public static Stream<MatchResult> matches(String input, Pattern... patterns) {
return StreamSupport.stream(new MultiPatternSpliterator(patterns,input), false);
}
private Pattern[] pattern;
private String input;
private int pos;
private PriorityQueue<Matcher> pendingMatches;
MultiPatternSpliterator(Pattern[] p, String inputString) {
super(inputString.length(), ORDERED|NONNULL);
pattern = p;
input = inputString;
}
@Override
public boolean tryAdvance(Consumer<? super MatchResult> action) {
if(pendingMatches == null) {
pendingMatches = new PriorityQueue<>(
pattern.length, Comparator.comparingInt(MatchResult::start));
for(Pattern p: pattern) {
Matcher m = p.matcher(input);
if(m.find()) pendingMatches.add(m);
}
}
MatchResult mr = null;
do {
Matcher m = pendingMatches.poll();
if(m == null) return false;
if(m.start() >= pos) {
mr = m.toMatchResult();
pos = mr.end();
}
if(m.region(pos, m.regionEnd()).find()) pendingMatches.add(m);
} while(mr == null);
action.accept(mr);
return true;
}
}
This facility allows to match multiple pattern in a (pattern1|pattern2|pattern3) fashion while still having the original groups of each pattern. So when searching for hell and llo in hello, it will find hell and not llo. A difference is that there is no guaranteed order if more than one pattern matches at the same position.
This can be used like
Pattern[] p = Stream.of(reTimeStamp, reHostName, reServiceTime)
.map(Pattern::compile)
.toArray(Pattern[]::new);
try (Stream<String> stream = Files.lines(Paths.get(inFileName))) {
List<String> timeStamp = stream
.flatMap(s -> MultiPatternSpliterator.matches(s, p))
.map(r -> r.group(1))
.collect(Collectors.toList());
timeStamp.forEach(System.out::println);
//Files.write(Paths.get(outFileName), dataSet);
}
While the overloaded method would allow to use MultiPatternSpliterator.matches(s, reTimeStamp, reHostName, reServiceTime) using the pattern strings to create a stream, this should be avoided within a flatMap operation that would recompile every regex for every input line. That’s why the code above compiles all patterns into an array first. This is what your original code also does by instantiating the PatternStreamers outside the stream operation.