匹配算法还是正则表达式?

时间:2011-04-13 12:49:15

标签: regex algorithm pattern-matching string-matching

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

示例代码段:

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

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

2 个答案:

答案 0 :(得分:3)

你可以为不同的格式制作一个正则表达式:

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

其中 fmt1 fmt2 等是个别的正则表达式,例如

(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),以便它们不算作捕获组,请查看更新的示例。

答案 1 :(得分:1)

如果您使用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。你可以在正则行中使用正则表达式与日志行中的其他东西分开的日期字符串,然后你可以使用各种DateTimeFormatter来尝试解析它们。