有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在流上执行正则表达式

我有一些大的文本文件,我将对它们进行连续匹配(只是捕获,而不是替换)。我认为将整个文件保存在内存中不是一个好主意,而是使用Reader

我所知道的输入是,如果有匹配,它不会跨越超过5行。所以我的想法是有一个缓冲区,只保留这5行左右,进行第一次搜索,然后继续。但它必须“知道”正则表达式匹配在哪里结束,这样才能起作用。e、 g如果匹配在第2行结束,则应从此处开始下一次搜索。有没有可能以一种有效的方式来做这样的事情


共 (6) 个答案

  1. # 1 楼答案

    也许Scanner.matchAll()就是你想要的。它简化了我的代码

    try(var scanner = new Scanner(Path.of(path), StandardCharsets.UTF_8)){
        var result = scanner.findAll(PATTERN)
                    .map(MatchResult::group)
                    .collect(Collectors.toSet());
    }
    
    
  2. # 2 楼答案

    您可以使用Scanner^{}方法:

    Scanner s = new Scanner(new File("thefile"));
    String nextMatch = s.findWithinHorizon(yourPattern, 0);
    

    ^{}上的api:

    If horizon is 0, then the horizon is ignored and this method continues to search through the input looking for the specified pattern without bound. In this case it may buffer all of the input searching for the pattern.

    附带说明:当在多行上进行匹配时,您可能希望查看常量Pattern.MULTILINEPattern.DOTALL

  3. # 3 楼答案

    Streamflyer能够在字符流上应用正则表达式

    请注意,我是这本书的作者

  4. # 4 楼答案

    正则表达式引擎的java实现看起来不适合流式处理

    我宁愿提倡另一种基于“导数组合”的方法

    研究人员Matt May在他的博客上发表了关于“导数组合子”的相关帖子,并建议在这里使用Scala实现:

    就我而言,我通过添加一些“捕获”功能成功地改进了这个实现,但我觉得它可能会对内存消耗产生重大影响

  5. # 5 楼答案

    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();
        }
    }
    
  6. # 6 楼答案

    使用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()));
    

    另一种方法可以是——

    List<String> results = Files.lines(Path.get("/home/testFile.txt")
                                  .parallelStream()
                                  .forEach(s -> "use regex")
                                  .collect(Collector.toList());