Действительно ли это регулярное выражение в PHP работает?

Я надеюсь, что эксперты по регулярному выражению могут сказать мне, почему это происходит не так:

Это регулярное выражение:

$pattern = '/(?<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?<filesize>.+) at/'; 

Должен соответствовать такой строке:

 [download] 87.1% of 4.40M at 107.90k/s ETA 00:05 [download] 89.0% of 4.40M at 107.88k/s ETA 00:04 [download] 91.4% of 4.40M at 106.09k/s ETA 00:03 [download] 92.9% of 4.40M at 105.55k/s ETA 00:03 

Верный? Есть ли что-то, что может пойти не так с этим регулярным выражением, которое не позволит ему соответствовать указанному выше вводу? Полное использование здесь:

 while(!feof($handle)) { $progress = fread($handle, 8192); $pattern = '/(?<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?<filesize>.+) at/'; if(preg_match_all($pattern, $progress, $matches)){ //matched } } в while(!feof($handle)) { $progress = fread($handle, 8192); $pattern = '/(?<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?<filesize>.+) at/'; if(preg_match_all($pattern, $progress, $matches)){ //matched } } 

Могло ли то, что читается fread, чтобы регулярное выражение работало правильно?

Мне действительно нужно подтверждение, поскольку я пытаюсь определить, почему он не работает на новом сервере. Этот вопрос связан с сценарием Change in Server Permits, который не работает. Может ли это быть связано с тем, что PHP.ini отличается?

Спасибо всем

Обновление 2

Я сделал тестовый скрипт для проверки регулярного выражения, но даже сам по себе он не работает?

 <?php error_reporting(E_ALL); echo 'Start'; $progress = "[download]75.1% of 4.40M at 115.10k/s ETA 00:09 [download] 77.2% of 4.40M at 112.36k/s ETA 00:09 [download] 78.6% of 4.40M at 111.41k/s ETA 00:08 [download] 80.3% of 4.40M at 110.80k/s ETA 00:07 [download] 82.3% of 4.40M at 110.30k/s ETA 00:07 [download] 84.3% of 4.40M at 108.33k/s ETA 00:06 [download] 85.7% of 4.40M at 107.62k/s ETA 00:05 [download] 87.5% of 4.40M at 107.21k/s ETA 00:05 [download] 89.5% of 4.40M at 105.10k/s ETA 00:04 [download] 90.7% of 4.40M at 106.45k/s ETA 00:03 [download] 93.2% of 4.40M at 104.92k/s ETA 00:02 [download] 94.8% of 4.40M at 104.40k/s ETA 00:02 [download] 96.5% of 4.40M at 102.47k/s ETA 00:01 [download] 97.7% of 4.40M at 103.48k/s ETA 00:01 [download] 100.0% of 4.40M at 103.15k/s ETA 00:00 [download] 100.0% of 4.40M at 103.16k/s ETA 00:00 "; $pattern = '/(?<percent>\d{1,3}\.\d{1,2})%\s+of\s+(?<filesize>[\d.]+[kBM]) at/'; if(preg_match_all($pattern, $progress, $matches)){ echo 'match'; } echo '<br>Done<br>'; ?> 

Я не знаком с именованным захватом, но я думаю, что в PHP это должно быть:

 $pattern = '/(?P<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?P<filesize>.+) at/'; 

Обратите внимание на P после вопросительного знака.

Источник:

  • Освоение регулярных выражений
  • Повторение синтаксиса регулярных выражений PCRE

Регулярное выражение кажется мне хорошо.

Однако есть некоторые вещи, которые я бы улучшил:

  • пробел с "\s+" , вместо " "
  • чисел с "\d" , а не с "[0-9]" (то же самое, это просто короче)
  • filesize не с ".+" , а с чем-то более конкретным

Это будет моя версия:

 (?<percent>\d{1,3}\.\d{1,2})%\s+of\s+(?<filesize>[\d.]+[kBM]) 

В зависимости от того, сколько вы ожидаете получить неправильные форматы чисел (я бы предположил: не очень вероятно), вы можете сократить его до:

 (?<percent>[\d.]+)%\s+of\s+(?<filesize>[\d.]+[kBM]) 

Если ваш поток на самом деле обеспечивает более 8 килобайт данных в одном чтении, вы, вероятно, обрезаете последнюю строку, что предотвратит ее совпадение. Попробуйте прочитать поток по одной строке за раз, используя fgets () .

Я бы использовал fgets () для чтения на основе строки, так как вы хотите совпадение с каждой строкой, я предполагаю. Если вы согласитесь на каждую строку вместо этого, вам не нужно будет использовать preg_match_all, но только preg_match.

Кажется, у вас всего 1 десятичный знак в процентах, но вы соответствуете 1,2 цифрам?

Есть ли что-то, что может пойти не так с этим регулярным выражением, которое не позволит ему соответствовать указанному выше вводу?

Не то, чтобы я мог видеть, но есть что-то, что пойдет не так, чтобы совместить это слишком много: если у вас действительно нет новых строк, то это:

 (?P<filesize>.+) at 

может с жадностью совладать от начала до последнего «на» на входе. Поэтому, если я сопоставляюсь со всем введенным вами примером ввода, я получаю <percent> of:

 75.1 

(хороший) и размер файла:

 4.40M at 115.10k/s ETA 00:09 [download] 77.2% of 4.40M at 112.36k/s ETA 00:09 [download] 78.6% of 4.40M at 111.41k/s ETA 00:08 [download] 80.3% of 4.40M at 110.80k/s ETA 00:07 [download] 82.3% of 4.40M at 110.30k/s ETA 00:07 [download] 84.3% of 4.40M at 108.33k/s ETA 00:06 [download] 85.7% of 4.40M at 107.62k/s ETA 00:05 [download] 87.5% of 4.40M at 107.21k/s ETA 00:05 [download] 89.5% of 4.40M at 105.10k/s ETA 00:04 [download] 90.7% of 4.40M at 106.45k/s ETA 00:03 [download] 93.2% of 4.40M at 104.92k/s ETA 00:02 [download] 94.8% of 4.40M at 104.40k/s ETA 00:02 [download] 96.5% of 4.40M at 102.47k/s ETA 00:01 [download] 97.7% of 4.40M at 103.48k/s ETA 00:01 [download] 100.0% of 4.40M at 103.15k/s ETA 00:00 [download] 100.0% of 4.40M 

(не совсем так). Чтобы избежать этого, используйте нежелательное соответствие «. +?» Или более конкретное выражение типа «[^] +» или версия Томалака.

Могло ли то, что читается fread, чтобы регулярное выражение работало правильно?

Да. Чтение в кусках довольно ненадежное: если строка «[скачать]» разделена на границу фрагмента, она не будет соответствовать и будет потеряна. Вы также можете:

  • не заботятся, или
  • прочитайте весь ввод сразу или
  • используйте линейное чтение, если на входе действительно есть символы новой строки (обычно есть)
  • управляйте буфером вручную, сохраняя последние n символов ввода (где n – индекс конца найденного окончательного соответствия) и добавление к нему нового входящего ввода.

Что касается различий между серверами, единственное, что я могу придумать, это то, что если один из серверов – это Windows и один a * ix, у них будут разные идеи о том, что такое новая строка, что может означать, что «есть ли новые строки или нет»? спутанность сознания.