我想有一个以上的regex如下所示,我如何将其添加到flatmap迭代器中,以便在单个流读取期间将该行的所有匹配值列表?
static String reTimeStamp="((?:2|1)\\d{3}(?:-|\\/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|\\/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|\\s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))";
static String reHostName="host=(\\\")((?:[a-z][a-z\\.\\d\\-]+)\\.(?:[a-z][a-z\\-]+))(?![\\w\\.])(\\\")";
static String reServiceTime="service=(\\d+)ms";
private static final PatternStreamer quoteRegex1 = new PatternStreamer(reTimeStamp);
private static final PatternStreamer quoteRegex2 = new PatternStreamer(reHostName);
private static final PatternStreamer quoteRegex3 = new PatternStreamer(reServiceTime);
public static void main(String[] args) throws Exception {
String inFileName = "Sample.log";
String outFileName = "Sample_output.log";
try (Stream<String> stream = Files.lines(Paths.get(inFileName))) {
//stream.forEach(System.out::println);
List<String> timeStamp = stream.flatMap(quoteRegex1::results)
.map(r -> r.group(1))
.collect(Collectors.toList());
timeStamp.forEach(System.out::println);
//Files.write(Paths.get(outFileName), dataSet);
}
}
这个问题是从匹配模式和使用Java8 stream将流写入文件中的扩展
您可以简单地连接流:
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);
}
但是请注意,这将在每一行中执行三个单独的搜索,这不仅意味着性能较低,而且一行中匹配项的顺序不会反映它们的实际出现情况。这似乎不是你的模式的问题,但个别搜索甚至暗示可能的重叠匹配。
该链接答案的PatternStreamer
还贪婪地将一个字符串的匹配项收集到ArrayList
中,然后创建流。基于spliterator
的解决方案更好,如本答案中所示。
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;
}
}
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);
}
虽然重载的方法允许使用multipatternspliterator.matches(s,reTimeStamp,reHostName,reServiceTime)
使用模式字符串创建流,但在flatmap
操作中应该避免这种情况,因为该操作将为每一行输入重新编译每一个regex。这就是为什么上面的代码首先将所有模式编译成一个数组。这也是您的原始代码通过在流操作之外实例化PatternStreamer
所做的事情。
问题内容: 我喜欢新的Java8 StreamAPI,并希望不仅将其用于一个文件。通常,我使用以下代码: 但是,如果可能的话,如何在一个流中读取两个文件呢? 问题答案: 没有任何额外的帮助程序功能或外部库,最简单的方法是: 如果尚未声明抛出受检查的异常,则可以 但是,a,我们不能这样做。有几种解决方法。一种是制作自己的版本,将其称为标准版本,然后将其作为捕获并重新抛出。另一种方法是使用抛出检查异常
假设我有这样一个列表: 是否可以使用Java8流从该列表中每隔一秒获取一个元素以获得以下内容? 或者甚至每三个元素? 基本上,我正在寻找一个函数来获取流的每n个元素:
问题内容: 我想一次从Python的文件/流中读取多个JSON对象。不幸的是刚刚s,至文件结束-; 似乎没有任何方法可以使用它来读取单个对象或延迟迭代这些对象。 有什么办法吗?使用标准库将是理想的选择,但是如果有第三方库,我会改用它。 目前,我将每个对象放在单独的行上并使用,但我真的不希望这样做。 使用范例 example.py in.txt 示例会话 问题答案: 这是一个非常简单的解决方案。秘诀
可以接受一个目录列表,这些目录为Spring boot应用程序托管yaml文件。 但是列出的目录必须有名为application的文件。yml,否则它们不会被拾取。 如果我的应用程序允许用户使用任何名称放置yaml文件,那么我不能使用此选项。 然后,我手动将文件名添加到属性中,如下所示 spring.config.locationfile1.ymlfile2.yml 每次添加新文件时,我都必须修改
我正在使用python,我有一个文件(
问题内容: 我想知道如何从单个文件夹中读取多个文件(无需指定文件名,只是它们是json文件)。 另外,有可能将它们转换为DataFrame吗? 能给我一个基本的例子吗? 问题答案: 一种选择是使用os.listdir列出目录中的所有文件,然后仅查找以’.json’结尾的文件: 现在,您可以使用pandas DataFrame.from_dict将json(此时为python字典)读入pandas数