从命令窗口输出获取特定子串(来自ping的时间)

时间:2015-01-19 09:57:41

标签: java regex ping

您好我从命令窗口执行ping信息。我想将这些信息读入我的Java代码中。我只想保留并使用时间信息。

这是我从ping命令输出的示例(输入到Java代码):

    Esecuzione di Ping 10.10.0.161 con 32 byte di dati:
Risposta da 10.10.0.161: byte=32 durata=3ms TTL=64

Statistiche Ping per 10.10.0.161:
    Pacchetti: Trasmessi = 1, Ricevuti = 1, 
    Persi = 0 (0% persi),
Tempo approssimativo percorsi andata/ritorno in millisecondi:
    Minimo = 3ms, Massimo =  3ms, Medio =  3ms

但我想只提取这个:

durata=3ms

这是代码:

Pattern pattern = Pattern.compile(".*?durata=(.*?ms) ",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);               
                Matcher m = null;
                while ((inputLine = in.readLine()) != null) {
                        m = pattern.matcher(inputLine);

                        if (m.find()) {
                            packet.setSendTime(Integer.parseInt(m.group(1)));

                                    piii= m.group(1);
                                    System.out.println(piii);
                        }
                }

修改

这是我的实际代码,结束了macther什么也没找到。

        Runtime r = Runtime.getRuntime();
        Process p = r.exec(pingCmd);

        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine())!= null){
            System.out.println(inputLine);
            pingResult += "\n"+inputLine;
        }

        Pattern pattern = Pattern.compile("durata=(\\d+)ms");
        Matcher m = null;

        while ((inputLine = in.readLine()) != null) {
               m = pattern.matcher(inputLine);

               if (m.find()) {
                     packet.setSendTime(Integer.parseInt(m.group(1)));
                     piii= m.group(1);
                     System.out.println("Time: " +piii);
                }
        }

        in.close();

我的输出没有在System.out.println(piii);

显示我想要的信息

为什么不通过代码提取持续时间?感谢

1 个答案:

答案 0 :(得分:1)

编辑以下OP编辑

问题在于您使用输入流的方式。您可以使用以下代码遍历它以打印出ping命令输出:

    while ((inputLine = in.readLine())!= null){
        System.out.println(inputLine);
        pingResult += "\n"+inputLine;
    }

但您尝试使用此代码进行处理:

    while ((inputLine = in.readLine()) != null) {
           m = pattern.matcher(inputLine);

不幸的是,ping命令已经完成,你已经处理了它的所有结果(输出并将它们附加到pingResult),你的输入流是空的,所以你永远不会进入第二个循环。

您有几个选择:

  1. 只需删除第一个while循环。这意味着您没有实时查看终端上ping命令的输出。
  2. 如果这是一个问题 - 将以下行移到第二个while循环中,然后删除第一个循环。

        System.out.println(inputLine);
    
  3. 如果你真的想保留第一个循环,另一个选择是使用你在第一个循环中收集的pingResult字符串作为第二个循环的输入。

  4. 我已经离开了以下部分来回答问题的其他方面,由OP编辑解决。


    所有方面的完整说明

    正如您的代码所代表的那样,我希望在您尝试

    时抛出异常
    packet.setSendTime(Integer.parseInt(m.group(1)))
    

    这是因为m.group(1)将返回匹配中的第一个组 - 这将是(在您的示例中)3ms。由于3ms不是纯粹的数字,我希望parseInt会抛出NumberFormatException。我试图通过将ping输出放入String并将in初始化为读取该字符串的BufferedReader来复制您的问题。我得到NumberFormatException

    要解决此问题,请更改Pattern正则表达式。术语括号定义组(参见the description of how this works in the API docs)。所以使用

            Pattern pattern = Pattern.compile(".*?durata=(.*?)ms ",Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);               
    

    请注意关闭支架位置的微小变化。有了这个 - 你的代码应该可以工作。

    <强> 修改

    添加了适合我的代码:

    public class PingReader
    {
    
        static final String pingOut = "    Esecuzione di Ping 10.10.0.161 con 32 byte"
                + " di dati:\n"
                + "Risposta da 10.10.0.161: byte=32 durata=3ms TTL=64\n\n"
                + "Statistiche Ping per 10.10.0.161:\n"
                + "    Pacchetti: Trasmessi = 1, Ricevuti = 1,\n"
                + "    Persi = 0 (0% persi),\n"
                + "Tempo approssimativo percorsi andata/ritorno in millisecondi:\n"
                + "    Minimo = 3ms, Massimo =  3ms, Medio =  3ms";
    
        public static void main(String[] args) throws NumberFormatException, IOException
        {
            StringReader inReader = new StringReader(pingOut);
            BufferedReader in = new BufferedReader(inReader);
            String inputLine = "";      
    
            Pattern pattern = Pattern.compile(".*?durata=(.*?)ms ",Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);               
            Matcher m = null;
            while ((inputLine = in.readLine()) != null) {
                    m = pattern.matcher(inputLine);
    
                    if (m.find()) {
                        int sendTime = (Integer.parseInt(m.group(1)));
    
                               String piii= m.group(1);
                                System.out.println(piii);
                    }
            }       
        }
    }
    

    编辑2

    与正则表达式一样,有很多方法可以获得你想要的东西。

    您可以将以下内容替换为您的模式,可能更容易理解正在发生的事情:

    Pattern pattern = Pattern.compile("durata=(\\d+)ms");
    

    在这种情况下,所需的字符串是已知的情况(ping将始终输出小写),因此不需要Pattern.CASE_INSENSITVE,我们不匹配行尾,因此Pattern.MULTLINE不是我的新模式,我们只匹配我们感兴趣的位,因此不需要Pattern.DOTALL

    请注意,d仅匹配数字,+符号表示我们需要其中一个。

    这仍然适用于我的例子。