Пытаясь узнать, каких "колёс" я наизобретал - решил сравнить метод поиска любой цифры перед заданным словом через функцию, написанный мной с тем же методом, но с помощью регулярного выражения. Какова же была моя радость, когда я увидел, что мой способ работает в большинстве случаем быстрее - особенно когда позиция искомой величины находится далее примерно 50 символов в строке. Привожу только тестовые результаты. Если надо - могу привести исходник функции. Общий смысл - найти необходимую цифру (если есть) перед заданным словом - с любым количеством пробелов, с десятичным знаком (.||,) или без. Тест: PHP: function correct_time() { $time=microtime(); $exp=explode(' ',$time); (float) $result=$exp[0]+$exp[1]; return $result; } $cicles=10000; // Количество циклов // Изначальный текст $text='Продаётся дом 45,7 кв м. В 150 метрах от остановки. Не агентство. 2 этажн.Возможен торг. 8,5 миллионов тел 576-2342-23.'; // Выражение поиска $posix="/(\d+(,?|.?)\d*)\s*(млн|миллионов|милионов)/"; $start=correct_time(); // Вычисление времени (преобразование в формат x.yy, где x - секунды и yy - доли секунд) for ($i=0; $i<=$cicles; $i++) preg_match($posix, $text, $result); $end=correct_time(); // Вычисление времени echo '<br>Функция preg_match = '.($end-$start).' секунд. Результат поиска = '.$result[1].'<br>'; $start=correct_time(); // Вычисление времени for ($i=0; $i<=$cicles; $i++) { // Алтернатива поиска - аналог posix- выражения $res=find_digit_at_word($text,'млн'); // Поиск. Функция возвращает цифру перед заданным словом. Если не найдено = false; if ($res==false) $res=find_digit_at_word($text,'миллионов'); // Если не найдено первое слово if ($res==false) $res=find_digit_at_word($text,'милионов'); // Если не найдено второе слово } $end=correct_time(); // Вычисление времени echo '<br>Новая функция = '.($end-$start).' секунд. Результат поиска= '.$res; Выдаёт: Функция preg_match = 0.760666131973 секунд. Результат поиска = 8,5 Новая функция = 0.567981004715 секунд. Результат поиска= 8.5 P.S. У меня как раз много циклов, и это замедляет значительно. P.S.2 Если строки заведомо малы - то лучше использовать регулярку. P.S.3 - Если надо - выложу код функции, может ещё можно подправить. P.S.4 Чёт у меня тут подсветка не работает
А зачем здесь цикл? Код (Text): for ($i=0; $i<=$cicles; $i++) preg_match($posix, $text, $result); есть же preg_match_all Из-за этого цикла и работает так медленно регулярное выражение. В целом мне кажется что с *_all будет быстрее, чем с вашей функцией.
Цикл - это только для того, чтобы это задание повторилось 10 тысяч раз. - чтобы было легче сравнивать время. Можешь поставить один цикл. или вообще без него - но тогда его выполнение займёт 0,00000001 секунды - ты не поймёшь, сколько реально ушло времени. А функции в обоих случаях ищут только по одному совпадению .В принципе перестроить на поиск всех - не сложно. и сравнить с preg_match_all
ваше выражение можно оптимизировать таким образом Код (Text): $posix="/(\d+(?:,|.)?\d?)\s*(?:млн|миллионов|милионов)/"; я бы предложил такой вариант, который еще быстрее: Код (Text): $posix="/([,.0-9]+)\s*(?:млн|миллионов|милионов)/"; но у данных выражений есть недостаток, они допускают неправильные совпадения: попробуйте применить их к строке Код (Text): $text='Продаётся дом 45,7 кв м. В 150 метрах от остановки. Не агентство. 2 этажн.Возможен торг. 8,5.9,4 миллионов тел 576-2342-23.'; мой вариант еще допускает совпадения в подобных строках Код (Text): $text='Продаётся дом 45,7 кв м. В 150 метрах от остановки. Не агентство. 2 этажн.Возможен торг. миллионов тел 576-2342-23.'; для решения, которое будет исключать неправильные совпадения, необходимо проанализировать входные данные, возможно этих шаблонов вполне достаточно
Хорошо. Попробую. Пока занимаюсь прочими работами, т.к. и эта функция работает сносно, а работы валом. Вот когда дойдёт речь дело ускорений и оптимизации - буду пробовать всё