正则表达式在日志文件中传递Apache的每一行

时间:2017-09-30 08:59:52

标签: java regex javac

需要帮助,我需要通过此正则表达式传递apache日志文件但不能正常工作,返回false。

private String accessLogRegex()
{
    String regex1 = "^([\\d.]+)"; // Client IP
    String regex2 = " (\\S+)"; // -
    String regex3 = " (\\S+)"; // -
    String regex4 = " \\[([\\w:/]+\\s[+\\-]\\d{4})\\]"; // Date
    String regex5 = " \"(.+?)\""; // request method and url
    String regex6 = " (\\d{3})"; // HTTP code
    String regex7 = " (\\d+|(.+?))"; // Number of bytes
    String regex8 = " \"([^\"]+|(.+?))\""; // Referer
    String regex9 = " \"([^\"]+|(.+?))\""; // Agent

    return regex1+regex2+regex3+regex4+regex5+regex6+regex7+regex8+regex9;
}

Pattern accessLogPattern = Pattern.compile(accessLogRegex());
Matcher entryMatcher;
String log = "64.242.88.10 | 2004-07-25.16:36:22 | "GET /twiki/bin/rdiff/Main/ConfigurationVariables HTTP/1.1" 401 1284 | Mozilla/4.6 [en] (X11; U; OpenBSD 2.8 i386; Nav)";

entryMatcher = accessLogPattern.matcher(log);
if(!entryMatcher.matches()){
  System.out.println("" + index +" : couldn't be parsed");
}

我已经包含了apache日志的样本,它是分开的pip(“|”)。

1 个答案:

答案 0 :(得分:0)

您是否有理由使用正则表达式?这些都非常容易出错,容易出错,并且可能成为维护的噩梦...

另一种方法可能是使用库,例如​​this one

也就是说,如果你想使用正则表达式,你的包含许多错误:

String regex1 = "^([\\d.]+)"; // while quite liberal, this should work
String regex2 = " (\\S+)"; // matches the first pipe
String regex3 = " (\\S+)"; // this will match the date field
String regex4 = " \\[([\\w:/]+\\s[+\\-]\\d{4})\\]"; // date has already been matched so this won't work, also this is all wrong
String regex5 = " \"(.+?)\""; // you're not matching the pipe character before the URL; also, why the ?
String regex6 = " (\\d{3})"; // HTTP code
String regex7 = " (\\d+|(.+?))"; // Why are you also matching any other characters than just digits?
String regex8 = " \"([^\"]+|(.+?))\""; // Your sample log line doesn't contain a referer
String regex9 = " \"([^\"]+|(.+?))\""; // Agent is not enclosed in quotes

您提供的示例日志行的一个可能的正则表达式解决方案是:

String regex1 = "^([\\d.]+)"; // digits and dots: the IP
String regex2 = " \\|"; // why match any character if you *know* there is a pipe?
String regex3 = " ((?:\\d+[-:.])+\\d+)"; // match the date; don't capture the inner group as we are only interested in the full date
String regex4 = " \\|"; // pipe
String regex5 = " \"(.+)\""; // request method and url
String regex6 = " (\\d{3})"; // HTTP code
String regex7 = " (\\d+)"; // Number of bytes
String regex8 = " \\|"; // pipe again
String regex9 = " (.+)"; // The rest of the line is the user agent

当然,如果其他日志行不遵循完全相同的格式,则可能需要进一步调整。