Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Зачистка повторов в строке


Автор: PROme 16.8.2005, 01:42
блин, снова я со своими регами
уже частично выучил, но никак не хватает времени smile СЕО все забирает... а может тут и не регами?
значит проблема не столько в сабже, сколько в его оптимальной реализации, т.к. надо будет значительное количество данных обрабатывать

нужно:

n=>2 пробелов заменять на 1 пробел
m=>1 табуляций заменять на 1 пробел
n=>1 + m=>1 пробелов + табуляций заменять на 1 пробел

как наиболее эффективно это организовать?
ЗЫ: все возможные знаки переноса "(\r\n|\n|\r)" из строки сразу удаляются за ненадобностью

Автор: Bikutoru 16.8.2005, 09:14
Первые два пункта и без регов прекрасно делаются:
Код

$string = <<<DATA
...
DATA;

while (($str = str_replace("\t", " ", $string)) != $string)
  $string = $str;

while (($str = str_replace("  ", " ", $string)) != $string)
  $string = $str;

А вот последний я не очень понял.

Автор: PROme 16.8.2005, 10:50
Bikutoru спасибо, ну это и так ясно... мне интересно, сколько ресурсов на это понадобиться? данных очень много, может есть что-то более прогрессивное?

Цитата
А вот последний я не очень понял.

ну если подряд идет один или более пробел и одна или более табуляция (в любом порядке и последовательности), все это надо заменять одним проблеом

Автор: Mal Hack 16.8.2005, 13:19
А я бы тут регуляркой воспользовался. Чтобы идти по тексту 2 раза.
Код

preg_replace( "#(\s{2,}|\t+|[\s\t]+)#s" , " " , $str );
preg_replace( "#[\n\r]#s" , "" , $str );

Автор: Bikutoru 16.8.2005, 15:06
Цитата(PROme @ 16.8.2005, 11:50)
если подряд идет один или более пробел и одна или более табуляция (в любом порядке и последовательности), все это надо заменять одним проблеом

Тогда то, что я написал, уже должно это сделать.

А насчет скорости, str_replace работает намного быстрее, чем preg_replace, но str_replace нужно использовать неоднократно, так что не все так очевидно. Мой совет - поэкспериментируй с разными данными, а результаты выложи сюда... Посмотрим на них и учтем на будующее...

Автор: Mal Hack 16.8.2005, 15:39
Цитата(Bikutoru @ 16.8.2005, 16:06)
А насчет скорости, str_replace работает намного быстрее, чем preg_replace, но str_replace нужно использовать неоднократно, так что не все так очевидно. Мой совет - поэкспериментируй с разными данными, а результаты выложи сюда... Посмотрим на них и учтем на будующее...

Хм... Ну вот тебе тест (Я оптимизировал регулярки):
Код

<?php

 function getmicrotime()
  {
   $mt = explode( " ", microtime() );
   return ( (float)$mt[0] + (float)$mt[1] );
  }

$string1 = file_get_contents( "preg_test.txt" );

$time_start1 = getmicrotime();

while (($str = str_replace("\t", " ", $string1)) != $string1)
  $string1 = $str;

while (($str = str_replace("  ", " ", $string1)) != $string1)
  $string1 = $str;

$string1 = str_replace( "\r" , "" , $string1 );
$string1 = str_replace( "\n" , "" , $string1 );

$time_end1 = getmicrotime();

$string2 = file_get_contents( "preg_test.txt" );

$time_start2 = getmicrotime();

$string2 = preg_replace( "#[\s\t]+#sS" , " " , $string2 );
$string2 = preg_replace( "#[\n\r]#S" , "" , $string2 );

$time_end2 = getmicrotime();

$test1 = round( ( $time_end1 - $time_start1 ) , 4 );
$test2 = round( ( $time_end2 - $time_start2 ) , 4 );

print "<br><br>Script works " . $test1 . "(1 str), " . $test2 . "(2 reg); Ðàçíèöà" . ( $test2 - $test1 ) . "(2-1) seconds<br><br>";

print "<pre>" . $string1 . "<br><br><br>" . $string2;

?>

Результат:
Код
Script works 0.0046(1 str), 0.0025(2 reg); Разница-0.0021(2-1) seconds
# при файле с двойным содержимом:
Script works 0.0116(1 str), 0.0047(2 reg); Разница-0.0069(2-1) seconds
# четверное
Script works 0.0761(1 str), 0.0118(2 reg); Разница-0.0643(2-1) seconds
# x12
Script works 1.5523(1 str), 0.0603(2 reg); Разница-1.492(2-1) seconds

Работал с файлом 68 килобайт (200 строк где-то). Файл кода. Его и приаттачиваю.

Автор: Bikutoru 16.8.2005, 18:08
Невероятно, но факт! preg_replace быстрее! Даже если убрать циклы!
Пробовал с другими файлами текстового содержимого размером от 15Кб до 300Кб - порядок примерно тот же!

Интересный факт - результаты работы получаются разными: $string1 != $string2 !

Автор: Mal Hack 16.8.2005, 18:38
Цитата(Bikutoru @ 16.8.2005, 19:08)
Интересный факт - результаты работы получаются разными: $string1 != $string2 !

При рэгах \nпробел остается пробелом без перевода строки, у тебя - стирается, почему - не понимаю smile

ЗЫ: А вся фишка тут в модификаторе S (s - больщое).. В принципе еще можно пару заюзать, но не хочу smile
Попробуй без него smile результат будет прямо противоположный.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)