Java正则表达式在花括号之间的匹配

19
我需要解析日志文件并获取时间以及相关函数调用字符串。在日志文件中,它是这样存储的:{"time" : "2012-09-24T03:08:50", "message" : "Call() started"}。由于在其他字符串字符中间可能会有多个记录时间函数调用,因此我希望使用正则表达式来查找并获取所有这些信息。我想获取包括花括号在内的整个记录信息。我已经尝试了以下方法。
Pattern logEntry = Pattern.compile("{(.*?)}");
Matcher matchPattern = logEntry.matcher(file);

并且

Pattern.compile("{[^{}]*}");
Matcher matchPattern = logEntry.matcher(file);

我一直收到非法重复的错误,请帮帮我!谢谢。

5个回答

38

您需要使用反斜线 '\' 转义 '{' 和 '}' 符号

因此:"{(.*?)}" 应转换为:"\\{(.*?)\\}"

在转义 '\' 之前,您必须先转义 '\' 符号。

请参见:http://www.regular-expressions.info/reference.html,获取需要转义的字符的全面列表...


这个方法很管用!谢谢。我之前尝试转义但总是遇到编译错误,因为我只使用了一个反斜杠。为什么需要双反斜杠呢?这是原始的错误提示:无效的转义序列(有效的包括 \b \t \n \f \r " ' \)。 - Eddie D
因为你需要转义转义字符,以便将其输入到正则表达式编译器中。例如:'\n'表示换行符,'\'表示反斜杠字符。由于在Java中正则表达式不是一等公民(在其他语言如JavaScript中是),所以它们是在运行时而不是编译时被编译的。 - ckozl
好的,我明白你在编译时说的是Java认为它只是一个字符串,因此需要使用"\"来获取"",然后在运行时将其用于正则表达式中。感谢你的所有帮助。 - Eddie D

9

花括号是正则表达式中用于重复分组的特殊字符,因此您必须对它们进行转义。

Pattern logEntry = Pattern.compile("\\{(.*?)\\}");

简单测试人员:

 public static void main(String[] args) throws Exception {
        String x =  "{\"time\" : \"2012-09-24T03:08:50\", \"message\" : \"Call() started\"}";
        Pattern logEntry = Pattern.compile("\\{(.*?)\\}");
        Matcher matchPattern = logEntry.matcher(x);

        while(matchPattern.find()) {
            System.out.println(matchPattern.group(1));
        }

    }

给我:
"time" : "2012-09-24T03:08:50", "message" : "Call() started"

8
你应该使用正向预查和反向预查:
(?<=\{)([^\}]+)(?=\})
  • (?<={) 匹配 { 后面的所有内容
  • ([^}]+) 匹配不包含 } 的任何字符串
  • (?={) 匹配 { 前面的所有内容

1
这是唯一不返回花括号本身的解决方案。 - slovit

0

这对于非嵌套括号完美运作,但对于像 (sum(x) * 100) / (sum(y) + sum(z)) 这样的表达式不适用。

[a-z]*[\{]+([a-zA-Z0-9]+)[\}]+ 可以工作。


0

在正则表达式中,{}有特殊含义,因此需要进行转义。

通常通过在要转义的字符前加上反斜杠来实现转义。在用方括号定义的字符类中,您不需要这样做

所以就像这样:

Pattern.compile("\{[^{}]*\}");

可能更接近你想要做的事情


3
由于反斜杠是Java的特殊字符,所以你必须对其进行转义。 - gtgaxiola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接