有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java正则表达式和组

我需要解析日志文件并获取一些变量值。 日志文件将包含一个字符串

String logStr = "21:19:03 -[ 8b4]- ERROR - Jhy AlarmOccure::OnAdd - Updated existing alarm: ID [StrValue1:StrValu2|StrValue3], Instance [4053], SetStatus [0], AckStatus [1], SetTime [DateValue4], ClearedTime [DateValue5]";

我需要将StrValue1、StrValue2、StrValue3、DateValue4和DateValue5设置为变量。一旦出现错误,这些值的字段就会发生变化

首先,我想至少得到StrValue1。但是没有得到预期的结果

Pattern twsPattern = Pattern.compile(".*?ID ?[([^]:]*):([^]|]*)|([^]]*)]");//.*ID\\s$.([^]:]*.):.([^]|]*.)|.([^]]*.).]
Matcher twsMatcher = twsPattern.matcher(logStr);
if(twsMatcher.find()){
    System.out.println(twsMatcher.start());
    System.out.println(twsMatcher.group());
    System.out.println(twsMatcher.end());
}

我无法理解regex中的分组内容


共 (4) 个答案

  1. # 1 楼答案

    试试regexp([a-zA-z]+) \[([^\]]+)\]

    对于字符串21:19:03 -[ 8b4]- ERROR - Jhy AlarmOccure::OnAdd - Updated existing alarm: ID [StrValue1:StrValu2|StrValue3], Instance [4053], SetStatus [0], AckStatus [1], SetTime [DateValue4], ClearedTime [DateValue5],它返回:

    • IDStrValue1:StrValu2|StrValue3
    • Instance4053
    • SetStatus0
    • AckStatus1
    • SetTimeDateValue4
    • ClearedTimeDateValue5

    你可以测试它

  2. # 2 楼答案

    长话短说,您的正则表达式缺少一些转义字符,比如[|(这一个,如果在字符类之外-[]

    因此,当您想要实际匹配[字符时,必须在java字符串中使用\[(或\\[)。而且,组([^]:]*)中的否定不是它看起来的那样。您可能只需要([^:]*),它匹配所有内容,直到:

    那么,为了使其工作,只需使用^{}来检索值。这是最终正则表达式的调整代码:

    String logStr = "21:19:03 -[ 8b4]- ERROR - Jhy AlarmOccure::OnAdd - Updated existing alarm: ID [StrValue1:StrValu2|StrValue3], Instance [4053], SetStatus [0], AckStatus [1], SetTime [DateValue4], ClearedTime [DateValue5]";
    Pattern twsPattern = Pattern.compile(".*?ID ?\\[([^:]*):([^|]*)\\|([^\\]]*)\\].*?SetTime ?\\[([^\\]]*)\\][^\\[]+\\[([^\\]]*)\\]");
    Matcher twsMatcher = twsPattern.matcher(logStr);
    if (twsMatcher.find()){
        System.out.println(twsMatcher.group(1)); // StrValue1
        System.out.println(twsMatcher.group(2)); // StrValu2
        System.out.println(twsMatcher.group(3)); // StrValue3
        System.out.println(twsMatcher.group(4)); // DateValue4
        System.out.println(twsMatcher.group(5)); // DateValue5
    }
    
  3. # 3 楼答案

    很高兴你这么做!你实际上做得很好。你需要避开方括号,而不是字符类,

    .*?ID ?\[
           ^
    

    希望你能意识到([^]:]*)的意思是,“不带(结束方括号或冒号的最长字符串。”

    您可能还想转义|,因为这是正则表达式中的一个交替运算符,

    \|
    
  4. # 4 楼答案

    我喜欢更一般的解决方案,但这里有一个非常具体的模式,如果适合你,你可以使用它。它将捕获字符串中的所有值,只要它们遵循相同的、非常特定的模式

    ID (?:\[([^\]:]+):([^\]|]+)\|([^\]]+)\]).*?SetTime \[([^\]]+)\], ClearedTime \[([^\]]+)\]
    

    结果如下:

    1: ID [StrValue1:StrValu2|StrValue3], Instance [4053], SetStatus [0], AckStatus [1], SetTime [DateValue4], ClearedTime [DateValue5]
      [1]: StrValue1
      [2]: StrValu2
      [3]: StrValue3
      [4]: DateValue4
      [5]: DateValue5
    

    Try it out

    每行有多个匹配项

    这个版本将只匹配ID、SetTime或ClearedTime字符串中的每个实例,后跟一个括号内的值

    (ID|SetTime|ClearedTime) \[([^\]]+)\
    

    结果

    1: ID [StrValue1:StrValu2|StrValue3]
      [1]: ID
      [2]: StrValue1:StrValu2|StrValue3
    1: SetTime [DateValue4]
      [1]: SetTime
      [2]: DateValue4
    1: ClearedTime [DateValue5]
      [1]: ClearedTime
      [2]: DateValue5
    

    Try it out