2016-07-20 9 views
0

Я пытался использовать Regex для анализа данных из результата, собранного стандартной командой ping. Однако некоторые шаблоны работают не так, как ожидалось, даже после проверки выражения регулярного выражения в онлайн-ригерах (они отлично работают в браузере).Сопряжение Java Regex, показывающее неожиданные результаты

Ошибка я получил следующим образом:

Exception in thread "main" java.lang.IllegalStateException: No match found 
    at java.util.regex.Matcher.group(Matcher.java:536) 
    at RegexMatches.parseGroupBytes(RegexMatches.java:77) 
    at RegexMatches.main(RegexMatches.java:13) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

Process finished with exit code 1 

Учитывая, что у меня нет опыта работы с Regex, я хотел бы знать, как действовать, чтобы исправить эту проблему. Класс я использовал, как показано ниже:

public class RegexMatches 
{ 
    public static void main(String args[]){ 
     String input = "[1463895254]PING www.andi.dz (213.179.181.44) 100(128) bytes of data.[1463895254]108 bytes from 213.179.181.44: icmp_seq=1 ttl=54 time=195 ms[1463895255]108 bytes from 213.179.181.44: icmp_seq=2 ttl=54 time=202 ms[1463895256]108 bytes from 213.179.181.44: icmp_seq=3 ttl=54 time=180 ms[1463895257]108 bytes from 213.179.181.44: icmp_seq=4 ttl=54 time=200 ms[1463895258]108 bytes from 213.179.181.44: icmp_seq=5 ttl=54 time=206 ms[1463895259]108 bytes from 213.179.181.44: icmp_seq=6 ttl=54 time=188 ms[1463895260]108 bytes from 213.179.181.44: icmp_seq=7 ttl=54 time=182 ms[1463895261]108 bytes from 213.179.181.44: icmp_seq=8 ttl=54 time=223 ms[1463895263]108 bytes from 213.179.181.44: icmp_seq=9 ttl=54 time=187 ms[1463895263]108 bytes from 213.179.181.44: icmp_seq=10 ttl=54 time=199 ms"; 
     String input2 = "[1463895327]PING www.gov.bw (168.167.134.24) 100(128) bytes of data.[1463895327]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=1 ttl=110 time=868 ms[1463895328]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=2 ttl=110 time=892 ms[1463895329]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=3 ttl=110 time=814 ms[1463895330]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=4 ttl=110 time=1009 ms[1463895331]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=5 ttl=110 time=1006 ms[1463895332]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=6 ttl=110 time=984 ms[1463895333]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=7 ttl=110 time=1004 ms[1463895334]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=8 ttl=110 time=1006 ms[1463895335]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=9 ttl=110 time=1013 ms[1463895336]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=10 ttl=110 time=578 ms[1463895336][1463895336]--- www.gov.bw ping statistics ---[1463895336]10 packets transmitted, 10 received, 0% packet loss, time 9007ms[1463895336]rtt min/avg/max/mdev = 578.263/917.875/1013.707/132.095 ms, pipe 2\n"; 
//  System.out.println(parse1(input)); 
     try{ 
      String op[] = parseGroupBytes(input); 
      System.out.println(op[0]); 
     } 
     catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public static String parse1(String input){ 
     Pattern p =Pattern.compile("\\[([0-9]{10})\\]PING"); 
     Matcher m = p.matcher(input); 
     if (m.find()) 
      return m.group(1); 
     else 
      return "error"; 
    } 

// Doesn't Work... 
    // patterns seem to be correct but only shows the first value 

    public static String[] parseGroupBytes(String input) throws BytesNotFoundException { 
     // Capture the bytes after (ip-address) outside the parenthesis 
     // Capture the bytes after (ip-address) inside the parenthesis 
     Pattern p1 = Pattern.compile("\\)\\s+(\\d+)\\("); 
     Matcher m1 = p1.matcher(input); 
     Pattern p2 = Pattern.compile("\\((\\d+)\\)\\s+bytes"); 
     Matcher m2 = p2.matcher(input); 
     String[] GroupBytes = new String[2]; 
     int x = m1.groupCount(); 
     int y = m2.groupCount(); 
     if(m1.find() || m2.find()){ 
      GroupBytes[0] = m1.group(1); 
      GroupBytes[1] = m2.group(1); 
       return GroupBytes; 
     } 
     else 
      throw new BytesNotFoundException(); 
    } 
} 
+0

'если (m1.find() || m2.find()) {' - Я думаю, что 'm1' нашел матч и' m2' не очень выполняться так же, как и после '||'. Запустите оба перед 'if', назначьте переменные bool, и это должно работать. –

+0

Почему вы нарушаете операцию в двух отдельных матчах? Просто найдите '' \\) \\ s + (\\ d +) \\ ((\\ d +) \\) \\ s + bytes "и извлеките' group (1) 'и' group (2) '. –

ответ

0

Вы делаете m1.find() || m2.find() так что если m1 находит совпадение м2 не будут опробованы, так что вы должны изменить его, например, до двух, если проверяет или объединяет регулярное выражение в один шаблон.

+0

Спасибо, что ответили. Это было намерено изолировать основную проблему, которая не имеет совпадений во время выполнения, в то время как онлайн-риджеры проверяют правильность шаблона. –

4

Проблема этот блок:

if(m1.find() || m2.find()){ 
    GroupBytes[0] = m1.group(1); 
    GroupBytes[1] = m2.group(1); 
    return GroupBytes; 
} 

Поскольку Вы входите в if условии, если какой-либо из спичек успеха для matchers m1 или m2, но при выполнении m2.group(1) он будет бросать IllegalStateExceptionтак m2.find() никогда не запускается на выполнение из-за || и m1.find() возвращает true.

Change, которые блокируют использование && вместо ||:

if(m1.find() && m2.find()){ 
    GroupBytes[0] = m1.group(1); 
    GroupBytes[1] = m2.group(1); 
    return GroupBytes; 
} 
else 
    throw new BytesNotFoundException(); 

Теперь код будет выполняться find() для обоих matchers m1 и m2 перед вызовом .group(1) для каждого Сличитель объектов.

+0

Спасибо за ответ. Да, вы абсолютно правы в том, что вы сказали, но я думаю, что я не упомянул проблему достаточно ясно. Я использовал || вместо && специально (временно), чтобы изолировать реальную проблему. Моя проблема заключается в отсутствии совпадений во время выполнения, в то время как я получаю то, что хочу от онлайн-ригеров онлайн. –

+0

Код, который вы предоставили, отлично работает после замены '||' на '&&'. Кроме того, если вы обновите свой код, который воспроизводит вашу проблему, я могу исследовать и предложить – anubhava

0

общественной группа String (ИНТ группа)

Возвращает входную подпоследовательность, захваченную данной группой во время предыдущей операции сравнения.

Проблема заключается в том, что вы не вызываете найти на м2 согласовани ... попробуйте это вместо

m1.find() | m2.find() 

Тот факт, что вы оцененную matches() как ложь во время выполнения, потому что find() пытается найти подпоследовательность вашего входа который соответствует шаблону, тогда как matches() оценивает весь ввод. если вы хотите, чтобы ваш пример работы с matches(), то вы должны изменить шаблон, как

Pattern p1 = Pattern.compile("^.*\\)\\s+(\\d+)\\(.*$"); 
Matcher m1 = p1.matcher(input); 
Pattern p2 = Pattern.compile("^.*\\((\\d+)\\)\\s+bytes.*$"); 
Matcher m2 = p2.matcher(input); 
... 
if(m1.matches() && m2.matches()) 
//then store values of each matcher group. 

Вы можете даже перегруппировать 2 модели в 1 одноместной модели, ограничивающей оба выражения p1 и p2 с И условие ...

Pattern p1 = Pattern.compile("(?=^.*\\)\\s+(\\d+)\\(.*$)(?=^.*\\((\\d+)\\)\\s+bytes.*$).*$"); 

Надеется, что это поможет вам спариваться :)

+0

Спасибо за ответ. Это было намерено изолировать основную проблему, которая не имеет совпадений во время выполнения, в то время как онлайн-риджеры проверяют, что шаблон правильный –

+0

Я отредактировал ответ для вас ... Надеюсь, это ответ на вашу реальную проблему :) –

+0

но это возвращает нулевые значения –