我正在尝试创建一个包含正则表达式字符串的枚举,同时确保该模式只编译一次,因为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 $”)只是一个例子。
答案 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" );
}
}
}
这意味着您可以同时查找所有模式,同时将模式保持为独立实体。进一步处理可以与字符串索引相关联。