Java - 正则表达式模式编译最佳实践(使用枚举)

时间:2015-02-06 06:32:10

标签: java regex enums

我正在尝试创建一个包含正则表达式字符串的枚举,同时确保该模式只编译一次,因为pattern compilation is expensive并且我重复使用相同的模式。我正在尝试根据所选枚举的类型实现动态编译的Pattern对象。但是,我坚持到下面。任何人都可以提供一些指导,或建议更好的方法来实现这一目标吗?

public enum LOG_SCANNER{
    FOO_STRING(".*XXXX$"),
    BAR_STRING(".*YYYY.*"),
    ;

    static Pattern p;
    static {
        p = Pattern.compile(regex); // Compilation failes here

    }


    String regex;
    private LOG_NAME_MATCHER(String regex) {
        this.regex = regex;
    }


}

编辑: 请注意,我没有使用正则表达式来搜索可以使用String.endsWith()或.contains()实现的内容。 (“。* XXXX $”)只是一个例子。

2 个答案:

答案 0 :(得分:2)

怎么样:

public enum LogNameMatcher{
    FOO_LOG(".*Foo\\.log$"),
    BAR_LOG(".*bar\\.log$");

    private final Pattern pattern;

    private LogNameMatcher(final String regex) {
        this.pattern = Pattern.compile(regex);
    }

    public Pattern getPattern() { return this.pattern; }
}

或(如评论中所述)

public final class LogNameMatcher {
    public static final Pattern FOO_LOG = Pattern.compile(".*Foo\\.log$");
    public static final Pattern BAR_LOG = Pattern.compile(".*bar\\.log$");

    private LogNameMatcher() {
        // util class
    }
}

答案 1 :(得分:0)

在讨论之后,另一种选择可能是收集某些集合中的模式:

List<Pattern> patterns = new ArrayList<>();
for( String ps: new String[]{ "...Foo...", "...bar...",... } ){
    patterns.add( Pattern.compile( ps ) );
}

使用此List of Pattern建立匹配的代码很简单,比迭代EnumSet更简单。

另外,你可能会这样做

String[] patstrs = new String[]{ "(.*Foo.*)", "(.*bar.*)", "(.blech.)"};
String ap = String.join( "|", patstrs );
Pattern p = Pattern.compile( ap );
String t = "a Foo is here";
Matcher m = p.matcher( t );
if( m.matches() ){
    for( int i = 1; i <= m.groupCount(); i++ ){
        if( m.group(i) != null ){
            System.out.println( "#" + i + " matches" );
        }
    }
}

这意味着您可以同时查找所有模式,同时将模式保持为独立实体。进一步处理可以与字符串索引相关联。