【问题标题】:Matching algorithm or regular expression?匹配算法还是正则表达式?
【发布时间】:2011-08-04 16:53:12
【问题描述】:

我有一个包含不同类型字符串行的巨大日志文件,我需要以“智能”方式从中提取数据。

示例 sn-p:

2011-03-05 node32_three INFO stack trace, at empty string asfa 11120023
--- - MON 23 02 2011 ERROR stack trace NONE      

例如,从每一行中提取日期的最佳方法是什么,与日期格式无关?

【问题讨论】:

  • 您的意思是“提取日期”吗?因为您的示例有两个日期。
  • 我是否正确理解您的巨大日志文件包含不同类型的行,其中日期可能以不同的格式显示?如果是这种情况,那么正则表达式可能不是一个好的解决方案。
  • @heykalrm:我编辑了您的问题以在您的示例中显示单独的行,但我不确定我是否正确。请检查并确认分行位置正确。
  • @MarcoS 是的,日期可能以不同的格式显示。如果不是正则表达式,您的解决方案是什么?
  • 我用另一种方法给出了答案:使用正则表达式来分隔日期字符串和 Joda 时间来解析它们。看我的回答。

标签: regex algorithm pattern-matching string-matching


【解决方案1】:

您可以为不同的格式创建一个正则表达式,如下所示:

 (fmt1)|(fmt2)|....

fmt1fmt2 等是单独的正则表达式,例如

(20\d\d-[01]\d-[0123]\d)|((?MON|TUE|WED|THU|FRI|SAT|SUN) [0123]\d [01]\d 20\d\d)

请注意,为了防止匹配任意数字,我相应地限制了年、月和日数字。例如,天数不能以 4 开头,月数也不能以 2 开头。

这给出了以下伪代码:

// remember that you need to double each backslash when writing the
// pattern in string form
Pattern p = Pattern.compile("...");    // compile once and for all
String s;
for each line 
    s = current input line;
    Matcher m = p.matcher(s);
    if (m.find()) {
        String d = m.group();    // d is the string that matched
        ....
    }

每个单独的日期模式都写在 () 中,以便找出我们拥有的格式,如下所示:

        int fmt = 0;
        // each (fmt) is a group, numbered starting with 1 from left to right
        for (int i = 1; fmt == 0 && i <= total number of different formats; i++) 
            if (m.group(i) != null) fmt = i;

为此,必须编写内部(正则表达式)组 (?regex),以便它们不计为捕获组,请查看更新的示例。

【讨论】:

  • 太棒了!上面的正则表达式是否有一些 Java 实现示例?
【解决方案2】:

如果你使用 Java,你可能想看看Joda time。另外,请阅读此question and related answers。我认为 Joda DateTimeFormat 应该为您提供解析日志文件的各种日期/时间格式所需的所有灵活性。

一个简单的例子:

String dateString = "2011-04-18 10:41:33";
DateTimeFormatter formatter = 
  DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dateTime = formatter.parseDateTime(dateString);

只需为您的日期/时间格式定义一个String[],并将每个元素传递给DateTimeFormat 以获取对应的DateTimeFormatter。您可以使用正则表达式将日期字符串与日志行中的其他内容分开,然后您可以使用各种DateTimeFormatters 来尝试解析它们。

【讨论】:

    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2022-08-17
    • 2014-05-06
    • 1970-01-01
    • 2019-03-30
    • 2011-05-01
    相关资源
    最近更新 更多