Java 如何从Apache服务器日志解析IP地址?

Java 如何从Apache服务器日志解析IP地址?,java,regex,Java,Regex,我必须从apache日志中找到常见的IP地址 12.1.12.1 9000 127.0.0.1-弗兰克[10/Oct/2000:13:55:36-0700]“获得 /apache_pb.gif HTTP/1.0“200 2326 "http://www.example.com/start.html" “Mozilla/4.08[en](Win98;I;Nav) 12.1.12.1 9000 192.145.1.23-弗兰克[10/Oct/2000:13:55:36-0700]“获得 /apach

我必须从apache日志中找到常见的IP地址

12.1.12.1 9000 127.0.0.1-弗兰克[10/Oct/2000:13:55:36-0700]“获得 /apache_pb.gif HTTP/1.0“200 2326 "http://www.example.com/start.html" “Mozilla/4.08[en](Win98;I;Nav)

12.1.12.1 9000 192.145.1.23-弗兰克[10/Oct/2000:13:55:36-0700]“获得 /apache_pb.gif HTTP/1.0“200 2326 "http://www.example.com/start.html" “Mozilla/4.08[en](Win98;I;Nav)

如何使用Java中的正则表达式提取IP地址(即每行中的第三个字)? 我还必须从中找到最常见的IP地址,以便找到机器人访问。
日志包含数百万行,因此regexp可能适用于此。

如果您确定它始终是第三个单词(如您所说),则可能根本不需要正则表达式。你可以通过简单的拆分来理解第三个单词


然而,已经有人问:

如果您确定它总是第三个单词(如您所说),那么您可能根本不需要正则表达式。你可以通过简单的拆分来理解第三个单词

然而,已经有人问:

这里有一个解决方案:

String str1 = "12.1.12.1 9000 127.0.0.1 - frank [10/Oct/2000:13:55:36"
            + " -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326 "
            + "\"http://www.example.com/start.html\" \"Mozilla/4.08 "
            + "[en] (Win98; I ;Nav)\"";

String str2 = "12.1.12.1 9000 192.145.1.23 - frank [10/Oct/2000:13:55"
            + ":36 -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326 "
            + "\"http://www.example.com/start.html\" \"Mozilla/4.08 "
            + "[en] (Win98; I ;Nav)\"";

Pattern p = Pattern.compile("\\S+\\s+\\S+\\s+(\\S+).*");

Matcher m = p.matcher(str1);
if (m.matches())
    System.out.println(m.group(1));

m = p.matcher(str2);
if (m.matches())
    System.out.println(m.group(1));
注册汇率明细:

  • \S+
    ,一个或多个非空白字符
  • \s+
    ,一个或多个空白字符
  • (\\S+)
    组1中捕获的一个或多个非空白字符
    • 这里有一个解决方案:

      String str1 = "12.1.12.1 9000 127.0.0.1 - frank [10/Oct/2000:13:55:36"
                  + " -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326 "
                  + "\"http://www.example.com/start.html\" \"Mozilla/4.08 "
                  + "[en] (Win98; I ;Nav)\"";
      
      String str2 = "12.1.12.1 9000 192.145.1.23 - frank [10/Oct/2000:13:55"
                  + ":36 -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326 "
                  + "\"http://www.example.com/start.html\" \"Mozilla/4.08 "
                  + "[en] (Win98; I ;Nav)\"";
      
      Pattern p = Pattern.compile("\\S+\\s+\\S+\\s+(\\S+).*");
      
      Matcher m = p.matcher(str1);
      if (m.matches())
          System.out.println(m.group(1));
      
      m = p.matcher(str2);
      if (m.matches())
          System.out.println(m.group(1));
      
      注册汇率明细:

      • \S+
        ,一个或多个非空白字符
      • \s+
        ,一个或多个空白字符
      • (\\S+)
        组1中捕获的一个或多个非空白字符

      访问日志文件的格式始终取决于配置文件设置。与其假设IP地址是第三个“字”,不如读取当前配置文件并根据
      LogFormat
      条目解析访问日志文件

      ApacheHttpd按照httpd.conf和Tomcat对server.xml的要求运行。xml是一个xml文件,这使得解析AccessLogValve成为一个标准过程


      这需要做更多的工作,但它将使您的应用程序更加灵活,以防需要持久化。对于这种方法,我认为字符串方法比正则表达式更容易使用。

      访问日志文件的格式始终取决于配置文件设置。与其假设IP地址是第三个“字”,不如读取当前配置文件并根据
      LogFormat
      条目解析访问日志文件

      ApacheHttpd按照httpd.conf和Tomcat对server.xml的要求运行。xml是一个xml文件,这使得解析AccessLogValve成为一个标准过程


      这需要做更多的工作,但它将使您的应用程序更加灵活,以防需要持久化。对于这种方法,我认为字符串方法比正则表达式更容易使用。

      正如其他人所指出的,您不需要正则表达式。您也不应该使用String.split,因为它也使用正则表达式。您可以改用StringTokenizer。假设您使用BufferedReader br读入每一行:

      String line = br.readLine();
      StringTokenizer st = new StringTokenizer(line, " ");
      st.nextToken();
      st.nextToken();
      String ip = st.nextToken();
      

      正如其他人指出的,您不需要正则表达式。您也不应该使用String.split,因为它也使用正则表达式。您可以改用StringTokenizer。假设您使用BufferedReader br读入每一行:

      String line = br.readLine();
      StringTokenizer st = new StringTokenizer(line, " ");
      st.nextToken();
      st.nextToken();
      String ip = st.nextToken();
      

      为什么要用正则表达式呢?只取第二和第三个空格之间的子字符串。我必须从数百万行中取。它会变慢。不,而且,如果从数百万行中取,它会变快,因为正则表达式的开销比简单地查找第二和第三个空格的索引,然后直接访问子字符串要大。为什么要用正则表达式呢?只取第二和第三个空格之间的子字符串。我必须从数百万行中取它。它会变慢。不,而且,如果从数百万行中取,它会变快,因为正则表达式比简单地查找第二和第三个空格的索引有更多的开销,然后直接访问子字符串。显然不能在顶部帖子上发表评论,所以我会在这里发表评论。要找到最常见的IP,您需要在某个地方维护每个IP的计数,可以在哈希映射中,也可以在磁盘上(因为这可能会占用太多内存)。我不知道正则表达式如何使查找最常见的IP更快、内存占用更少。显然,我无法在顶部帖子上发表评论,所以我将在这里发表评论。要找到最常见的IP,您需要在某个地方维护每个IP的计数,可以在哈希映射中,也可以在磁盘上(因为这可能会占用太多内存)。我不知道正则表达式如何使查找最常见的IP更快、内存占用更少。