简体   繁体   English

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

[英]Java - regex pattern compilation best practice (with enum)

I'm trying to create an enum which holds the regex string, while making sure that the pattern only compiles once because pattern compilation is expensive and I do reuse the same pattern a lot. 我试图创建一个包含正则表达式字符串的枚举,同时确保模式仅编译一次,因为模式编译非常昂贵,而且我确实重复使用了很多相同的模式。 I'm trying to achieve a dynamically compiled Pattern object depending of the type of enum selected. 我试图根据所选枚举的类型实现动态编译的Pattern对象。 However, I'm stuck at the following. 但是,我坚持以下几点。 Can anyone kindly provide some guidance, or suggest a better way of achieving this? 任何人都可以提供一些指导,或者提出实现此目标的更好方法吗?

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;
    }


}

edit: Please note that i'm not using regex to search for something that could be achieved with String.endsWith() or .contains(). 编辑:请注意,我没有使用正则表达式来搜索可以用String.endsWith()或.contains()实现的功能。 ( ".*XXXX$" ) is simply an example. (“。* XXXX $”)只是一个示例。

What about: 关于什么:

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; }
}

or (as stated in comments) 或(如评论中所述)

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
    }
}

Following the discussion, an alternative might be to collect the patterns in some Collection: 在讨论之后,一种替代方法可能是在某些Collection中收集模式:

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

Code using this List of Pattern to establish a match is straightforward, more so than iterating over an EnumSet. 使用此模式列表建立匹配的代码非常简单,比在EnumSet上进行迭代更是如此。

Also, you might do 另外,你可能会做

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" );
        }
    }
}

This is meant to indicate that you can look for all patterns at the same time while maintaining the patterns as isolated entities. 这表示您可以同时查找所有模式,同时将这些模式保持为孤立的实体。 Further processing can be associated with the string index. 进一步的处理可以与字符串索引相关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM