Java 在流上执行正则表达式
我有一些大的文本文件,我将对它们进行连续匹配(只是捕获,而不是替换)。我认为把整个文件保存在内存中不是一个好主意,而是使用Java 在流上执行正则表达式,java,regex,Java,Regex,我有一些大的文本文件,我将对它们进行连续匹配(只是捕获,而不是替换)。我认为把整个文件保存在内存中不是一个好主意,而是使用读卡器 我所知道的输入是,如果有匹配,它不会跨越超过5行。所以我的想法是有一个缓冲区,只保留这5行左右,进行第一次搜索,然后继续。但它必须“知道”正则表达式匹配在哪里结束,这样才能起作用。e、 g如果匹配在第2行结束,则应从此处开始下一次搜索。有没有可能以高效的方式执行类似操作?您可以使用扫描仪和以下方法: 从api上: 如果horizon为0,则忽略该horizon,此方法
读卡器
我所知道的输入是,如果有匹配,它不会跨越超过5行。所以我的想法是有一个缓冲区,只保留这5行左右,进行第一次搜索,然后继续。但它必须“知道”正则表达式匹配在哪里结束,这样才能起作用。e、 g如果匹配在第2行结束,则应从此处开始下一次搜索。有没有可能以高效的方式执行类似操作?您可以使用
扫描仪和以下方法:
从api上:
如果horizon为0,则忽略该horizon,此方法继续在输入中搜索指定的模式,而不进行绑定。在这种情况下,它可以缓冲模式的所有输入搜索
旁注:当在多行上进行匹配时,您可能希望查看常量模式。多行和模式。DOTALL
能够在字符流上应用正则表达式
请注意,我是它的作者。使用Java8,您可以非常简单地并行地完成这项工作-
// Create a pattern-matcher
private static final Pattern emailRegex = Pattern.compile("([^,]+?)@([^,]+)");
//Read content of a file
String fileContent = Files.lines(Path.get("/home/testFile.txt")
.collect(Collector.join(" "));
// Apply the pattern-matcher
List<String> results = matcherStream(emailRegex.matcher(fileContent))
.map(b -> b[2])
.collect(Collector.toList()));
//创建模式匹配器
私有静态最终模式emailRegex=Pattern.compile(([^,]+?)@([^,]+)”;
//读取文件内容
字符串fileContent=Files.lines(Path.get(“/home/testFile.txt”)
.collect(Collector.join(“”));
//应用模式匹配器
List results=matcherStream(emailRegex.matcher(fileContent))
.map(b->b[2])
.collect(Collector.toList());
另一种方法可以是-
List<String> results = Files.lines(Path.get("/home/testFile.txt")
.parallelStream()
.forEach(s -> "use regex")
.collect(Collector.toList());
List results=Files.lines(Path.get(“/home/testFile.txt”)
.parallelStream()
.forEach(s->“使用正则表达式”)
.collect(Collector.toList());
正则表达式引擎的java实现看起来不适合流式处理
我宁愿提倡另一种基于“导数组合子”的方法
研究人员Matt May在他的博客上发表了关于“导数组合子”的相关文章,并建议在此处使用Scala实现:
在我这方面,我通过添加一些“捕获”功能成功地改进了这个实现,但我觉得它可能会对内存消耗产生重大影响。也许Scanner.matchAll()
就是您想要的。它简化了我的代码
try(var scanner=new scanner(Path.of(Path),StandardCharsets.UTF_8)){
var result=scanner.findAll(模式)
.map(匹配结果::组)
.collect(收集器.toSet());
}
+1;并阅读API以了解Scanner
如何处理IOException
。您从另一个答案中获取了此内容,但没有引用它()它甚至没有完全完成。matcherStream
方法没有定义。您可以通过添加示例代码用法和示例输出来增强您的有前途的帖子吗?太糟糕了,您的库不再维护了。:-(有好的替代方案吗?
List<String> results = Files.lines(Path.get("/home/testFile.txt")
.parallelStream()
.forEach(s -> "use regex")
.collect(Collector.toList());
import java.io.*; //BufferedReader //FileReader //FileWriter //PrintWriter
import java.io.IOException;
import java.util.Scanner;
import java.util.regex.*;
public class ScannerReader {
public static void main(String[] args) {
try {
ReadDataFromFileTestRegex("[A-Za-z_0-9-%$!]+@[A-Za-z_0-9-%!$]+\\.[A-Za-z]{2,4}",
"C:\\Users\\Admin\\Desktop\\TextFiles\\Emails.txt",
"C:\\Users\\Admin\\Desktop\\TextFiles\\\\output.txt");
} catch (Exception e) {
System.out.println("File is not found");
e.printStackTrace();
}
}
public static void ReadDataFromFileTestRegex (String theReg, String FileToRead, String FileToWrite) throws Exception {
PrintWriter Pout = new PrintWriter(FileToWrite);
Pattern p = Pattern.compile(theReg);
BufferedReader br = new BufferedReader (new FileReader(FileToRead));
String line = br.readLine();
while (line != null) {
Matcher m = p.matcher(line);
while (m.find()) {
if (m.group().length() != 0) {
System.out.println( m.group().trim());
}
System.out.println("Start index: " + m.start());
System.out.println("End index : " + m.end());
Pout.println(m.group()); //print the result to the output file
}
line = br.readLine();
}
Pout.flush();
br.close();
Pout.close();
}
}