Java 模式匹配通过排除最后一个大括号来提取大括号

Java 模式匹配通过排除最后一个大括号来提取大括号,java,regex,Java,Regex,我试图从下面提到的表达式中提取字符 private static final String FILTER_X = "userid=UUID.randomUUID();empid=lkjdlfd ;eventType=Usage" + ";classid=1" + ";fromDate=2017-08-11Z10:00:00+1:00" + ";toDate=2017-09-11Z10:00:00+1:00" + ";(classno=10 or(c

我试图从下面提到的表达式中提取字符

private static final String FILTER_X = "userid=UUID.randomUUID();empid=lkjdlfd ;eventType=Usage"
            + ";classid=1" + ";fromDate=2017-08-11Z10:00:00+1:00" + ";toDate=2017-09-11Z10:00:00+1:00"
            + ";(classno=10 or(classno<4 and joiningDate>=2017-08-11Z10:00:00+1:00));"
            + "(classno=10 or(classno<10 and joiningDate>=2017-08-11Z10:00:00+1:00))";

StringTokenizer tokens = new StringTokenizer(FILTER_X, ";");
        while (tokens.hasMoreTokens()) {
            String token = tokens.nextToken();
            System.out.println(token);
            Pattern p1 = Pattern.compile("\\((.*?)\\)");
            Matcher m1 = p1.matcher(token);
            while (m1.find()) {
                System.out.println(m1.group(1));
            }
        }
private static final String FILTER\u X=“userid=UUID.randomuid();empid=lkjdlfd;eventType=Usage”
+“classid=1”+“fromDate=2017-08-11Z10:00:00+1:00”+“toDate=2017-09-11Z10:00:00+1:00”
+“;(classno=10或(classno=2017-08-11Z10:00:00+1:00));”
+“(类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00))”;
StringTokenizer令牌=新的StringTokenizer(过滤器_X,“;”);
while(tokens.hasMoreTokens()){
String token=tokens.nextToken();
System.out.println(令牌);
模式p1=Pattern.compile(“\\(.*?\\)”;
匹配器m1=p1.匹配器(令牌);
而(m1.find()){
系统输出println(m1组(1));
}
}
输出:

> > userid=UUID.randomUUID()
> > 
> > empid=lkjdlfd   eventType=Usage  classid=1
> > fromDate=2017-08-11Z10:00:00+1:00  toDate=2017-09-11Z10:00:00+1:00
> > (classno=10 or(classno<4 and joiningDate>=2017-08-11Z10:00:00+1:00))
> > classno=10 or(classno<4 and joiningDate>=2017-08-11Z10:00:00+1:00
> > (classno=10 or(classno<10 and joiningDate>=2017-08-11Z10:00:00+1:00))
> > classno=10 or(classno<10 and joiningDate>=2017-08-11Z10:00:00+1:00
>userid=UUID.randomUUID()
> > 
>>empid=lkjdlfd eventType=Usage classid=1
>>从日期=2017-08-11Z10:00:00+1:00到日期=2017-09-11Z10:00:00+1:00
>>(类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00))
>>类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00
>>(类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00))
>>类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00
我正在尝试筛选以大括号开头的字符串。对于上面的模式,它将在大括号内打印字符串 但它并没有打印最后一个括号,我希望输出为

(类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00))


这意味着它应该跳过最后一个大括号。有人能告诉我模式有什么问题吗?

您在正则表达式中使用了惰性量词。这导致正则表达式引擎停止匹配
)之间的最短匹配

您可以使regex变懒,并避免捕获组,因为您的预期结果是
之间的完全匹配

final static String FILTER_X=“userid=UUID.randomUUID();empid=lkjdlfd;eventType=Usage”
+“classid=1”+“fromDate=2017-08-11Z10:00:00+1:00”+“toDate=2017-09-11Z10:00:00+1:00”
+“;(classno=10或(classno=2017-08-11Z10:00:00+1:00));”
+“(类别编号=10或(类别编号=2017-08-11Z10:00:00+1:00))”;
最终模式p1=Pattern.compile(“\\(.\\)”;
StringTokenizer令牌=新的StringTokenizer(过滤器_X,“;”);
while(tokens.hasMoreTokens()){
String token=tokens.nextToken();
System.out.println(“>:”+令牌);
匹配器m1=p1.匹配器(令牌);
而(m1.find()){
System.out.println(“>>:”+m1.group());
}
}
最好将
模式设置为final,并将其保持在循环之外

我试图过滤以大括号开头的字符串

我的做法:

(?<=^|.;)\([^;\n]+(?=;|$)

(?<=      # Assert this group matches
^|.;      # Start of line OR 1 char, then a semicolon
)         # End of assertion
\([^;\n]+ # An opening brace, then one or more chars of not a semicolon OR a newline
(?=       # Assert this group matches
;|$       # A semicolon OR end-of-line
)         # End of assertion
(?
(?<=^|.;)\([^;\n]+(?=;|$)

(?<=      # Assert this group matches
^|.;      # Start of line OR 1 char, then a semicolon
)         # End of assertion
\([^;\n]+ # An opening brace, then one or more chars of not a semicolon OR a newline
(?=       # Assert this group matches
;|$       # A semicolon OR end-of-line
)         # End of assertion