Home > Software engineering >  Regex filter for file search Java
Regex filter for file search Java

Time:05-12

I'm quite new to using regex so I'm having problems with my current code. I created an Abstract File Search that returns a List of Files. I would like this searcher to be filtered by a regex (have ex. the extension it looks for based on a regex filter).

The code of my Abstract Searcher:

public abstract class AbstractFileDiscoverer implements IDiscoverer {

    private final Path rootPath;

    AbstractFileDiscoverer(final Path rootPath) {
        super();
        this.rootPath = rootPath;

    }

    protected List<File> findFiles() throws IOException {
        if (!Files.isDirectory(this.rootPath)) {
            throw new IllegalArgumentException("Path must be a directory");
        }

        List<File> result;

        try (Stream<Path> walk = Files.walk(this.rootPath)) {
            result = walk.filter(p -> !Files.isDirectory(p)).map(p -> p.toFile())
                    .filter(f -> f.toString().toLowerCase().endsWith("")).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return null;
    }

}

I would like the following part to be filtered by the regex, so that only the files that the regex returns as true (for .bat and .sql files) to be collected.

result = walk.filter(p -> !Files.isDirectory(p)).map(p -> p.toFile())
                    .filter(f -> f.toString().toLowerCase().endsWith("")).collect(Collectors.toList());

Could anyone help me achieving it?

FIRST EDIT: I'm aware that toString().toLowerCase().endsWith("") always returns true, I actually need the regex there instead of an String with the extension. I forgot to mention that.

CodePudding user response:

Try this website: https://regexr.com/ and paste the regex . (?:.sql|.bat)$ for an explanation.

In code it'd look like this:

Stream.of("file1.json", "init.bat", "init.sql", "file2.txt")
            .filter(filename -> filename.matches(". (?:.sql|.bat)$"))
            .forEach(System.out::println);

CodePudding user response:

There is a famous quote from Jamie Zawinski about using regular expressions when simpler non-regex code will do.

In your case, I would avoid using a regular expression and would just write a private method:

private static boolean hasMatchingExtension(Path path) {
    String filename = path.toString().toLowerCase();
    return filename.endsWith(".bat") || filename.endsWith(".sql");
}

Then you can use it in your stream:

result = walk.filter(p -> !Files.isDirectory(p)).
    .filter(p -> hasMatchingExtension(p))
    .map(p -> p.toFile())
    .collect(Collectors.toList());

(Consider returning List<Path> instead. The Path class is the modern replacement for the File class, some of whose methods that actually operate on files have design issues.)

  • Related