ceran
ceran

Reputation: 1412

Apache Camel: making a regex work with File2's include filter

I'm using Camel to process files from a directory. However, I want my camel route to only process files whose names match a specific regex pattern. Therefore, I added the include option to the File2 configuration and passed in the required regular expression.

An example of the filename pattern:

somerandomname-2017-10-02T13-23-42+02-00.zip

The regular expression I came up with:

^[A-Za-z0-9_]+\-\d{4}\-\d{2}\-\d{2}T\d{2}\-\d{2}\-\d{2}\+\d{2}\-\d{2}\.zip$

The File2 component's string I'm passing to from(...):

file://...?include=^[A-Za-z0-9_]+\-\d{4}\-\d{2}\-\d{2}T\d{2}\-\d{2}\-\d{2}\+\d{2}\-\d{2}\.zip$&...

However, all files are ignored. It works when changing the regular expression to a much simpler one, such as .*\.zip, so the problem is definitely related to include and my pattern. I also tried it without the start and end operators (^ and $) with no success:

.*?[A-Za-z0-9_]+\-\d{4}\-\d{2}\-\d{2}T\d{2}\-\d{2}\-\d{2}\+\d{2}\-\d{2}\.zip

Any help is appreciated.

edit 1: I tested the regex with String.matches and Matcher.matches (assuming that this is what Camel uses internally) without any problems. I'm using the current Camel version 2.19.3.

edit 2: I tried to find the minimal working pattern, and while .*?\d{2}\-\d{2}\.zip still works, .*?\+\d{2}\-\d{2}\.zip doesn't. So it seems that it has something to do with the + sign.

Upvotes: 1

Views: 2414

Answers (2)

Guillaume Lecroc
Guillaume Lecroc

Reputation: 63

The plus sign '+' is replaced by a space ' ', even if the regex is encoded.

This is used by camel in the quartz2 component where the cron expression is separated by '+' : cron=0/5+*+*+1/1+*+?+*

The solution is to use RAW(^myRegex.+$)

Upvotes: 0

Erik Karlstrand
Erik Karlstrand

Reputation: 1537

I'd suggest using the filter-option instead. That way you eliminate the possibility that your regex gets URL-encoded (which I suspect might be the case).

public class MyFilter<T> implements GenericFileFilter<T> {
    @Override
    public boolean accept(GenericFile<T> file) {
        if (file.getFileName().matches("^[A-Za-z0-9_]+\-\d{4}\-\d{2}\-\d{2}T\d{2}\-\d{2}\-\d{2}\+\d{2}\-\d{2}\.zip$"))
            return true;
        return false;
    }
}

Then you could reference your bean in the filter-option like so:

<from uri="file:///someDir?filter=#myFilter" />

Upvotes: 3

Related Questions