Работает ли это регулярное выражение в PHP? - PullRequest
1 голос
/ 21 марта 2009

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

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

$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
    }
}

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

Мне действительно нужно подтверждение, так как я пытаюсь определить, почему он не работает на новом сервере. Этот вопрос относится к Изменение в сценарии «Разрешить сервер» не работает. Может ли это быть из-за того, что 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>';    

?>

Ответы [ 5 ]

5 голосов
/ 21 марта 2009

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

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

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

* Источник: 1009 *

1 голос
/ 21 марта 2009

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

1 голос
/ 21 марта 2009

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

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

1 голос
/ 21 марта 2009

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

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

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

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

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

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

(?<percent>[\d.]+)%\s+of\s+(?<filesize>[\d.]+[kBM])
0 голосов
/ 21 марта 2009

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

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

(?P<filesize>.+) at

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

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, а другой - * ix, у них будут разные представления о том, что такое перевод строки, что может привести к тому, что «есть переводы строки или не? »путаница.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...