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

时间:2017-08-19 12:19:17

标签: 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(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));
            }
        }

输出:

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

我正在尝试过滤以大括号开头的字符串。对于上面的模式,它在大括号内打印字符串 但它不是打印我期待输出的最后一个括号

  

(classno = 10或(classno&lt; 4 and joinedDate&gt; = 2017-08-11Z10:00:00 + 1:00))

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

2 个答案:

答案 0 :(得分:1)

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

您可以使正则表达式延迟,并避免捕获组,因为您的预期结果与()完全匹配。

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

final Pattern p1 = Pattern.compile("\\(.*\\)");
StringTokenizer tokens = new StringTokenizer(FILTER_X, ";");
while (tokens.hasMoreTokens()) {
    String token = tokens.nextToken();
    System.out.println("> : " + token);
    Matcher m1 = p1.matcher(token);
    while (m1.find()) {
        System.out.println(">> : " + m1.group());
    }
}

最好让Pattern最终并将其保持在循环之外。

答案 1 :(得分:0)

  

我正在尝试过滤以大括号开头的字符串。

我的方法:

(?<=^|.;)\([^;\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

PCRE demo