#php #regex #preg-match #preg-match-all
#php #регулярное выражение #preg-match #preg-match-all
Вопрос:
Я хотел бы проанализировать вывод команды ping в Linux. Мой текущий код работает нормально, единственная проблема в том, что он анализирует только первый результат. Я хотел бы изменить его, чтобы анализировать каждую строку.
Также следует проанализировать строки, отмеченные красным: https://i.imgur.com/GDE19Xl.png Что мне нужно изменить, чтобы сделать это?
Это мое текущее регулярное выражение: https://regex101.com/r/uH0XwP/1
Это текущий PHP-код:
$re = '/^PINGb[^(]*(([^)]*))s([^.]*)..*?^(d sbytes).*?icmp_seq=(d ).*?ttl=(d ).*?time=(.*?ms).*?(d )spacketsstransmitted.*?(d )sreceived.*?(d %)spacketsloss.*?times(d ms).*?=s([^/]*)/([^/]*)/([^/]*)/(.*?)sms/ims';
$str = 'PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=58 time=0.816 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=58 time=0.883 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=58 time=0.743 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=58 time=0.613 ms
--- 1.1.1.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3033ms
rtt min/avg/max/mdev = 0.613/0.763/0.883/0.105 ms
';
preg_match($re, $str, $matches, PREG_OFFSET_CAPTURE, 0);
// Print the entire match result
var_dump($matches);
Большое спасибо.
С наилучшими пожеланиями
Комментарии:
1. Вероятно, это не то, что вы хотите, но я бы разбил это на правила для каждой строки, разделил результаты ping на строки и перебирал их, выполняя
preg_match
тесты if для каждого. Это кажется менее красноречивым, но его намного проще отлаживать и рассуждать. Вы также можете регистрировать отдельные строки, которые не соответствуют вашим шаблонам, чтобы найти крайние случаи.
Ответ №1:
Если ваши данные структурированы таким образом, вы можете использовать G
привязку
(?:^PINGb[^(]*(([^)]*))s([^.]*)..*|G(?!^))R^(d sbytes).*?icmp_seq=(d ).*?ttl=(d ).*?time=(.*?ms).*(?:s ---.*R(d )spacketsstransmitted.*?(d )sreceived.*?(d %)spacketsloss.*?times(d ms)R.*=s([^/]*)/([^/]*)/([^/]*)/(.*?)sms)?
Демонстрация регулярных выражений
В вашем шаблоне есть несколько случаев .*?
, которые также могут быть заменены более конкретной частью, такой как пробелы или цифры, с необязательной десятичной частью
(?:^PINGb[^(]*(([^)]*))s([^.]*).|G(?!^))R(d sbytes).*?icmp_seq=(d )h ttl=(d ).*?time=(d (?:.d )?h ms).*(?:s ---.*R(d )spacketsstransmitted.*?(d )sreceived,h*(d %)spacketsloss,h times(d ms)R.*=s(d (?:.d )?)/(d (?:.d )?)/(d (?:.d )?)/(d (?:.d )?)sms)?
Затем с помощью preg_match_all значения находятся в группе 3 — группа 6
Другой вариант — сопоставить повторяющиеся промежуточные данные в группе захвата и обработать эти строки отдельно. В следующем шаблоне группа захвата 3 содержит повторяющиеся строки, которые вы могли бы проанализировать отдельно на втором шаге.
^PINGb[^(]*(([^)]*))s([^.]*).R(d sbytes.*?icmp_seq=d h ttl=d h time=d (?:.d )?h ms(?:Rd sbytes.*?icmp_seq=d h ttl=d h time=d (?:.d )?h ms)*)R ---.*R(d )spacketsstransmitted.*?(d )sreceived,h*(d %)spacketsloss,h times(d ms)R.*=s(d (?:.d )?)/(d (?:.d )?)/(d (?:.d )?)/(d (?:.d )?)sms
Смотрите другую демонстрацию регулярных выражений.