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


Автор: tolik777 11.5.2007, 08:15
Есть текст. В нем нужно к примеру 10-20% букв "у" заменить на "u", буквы "л" на "l".
Какой алгоритм попроще посоветуете?

Я вот такой придумал: разбиваем весь текст по словам на массив путем explode. Затем mt_rand (0,10). Если меньше 2-х, то заменяем str_replace. Затем делаем implode.

Автор: Всемогущий 11.5.2007, 09:15
нужно изменить одну строку
добавить if и вычисление вероятности
доделаю чуть позже

сейчас работает как будто 100%
Код

 $textQ=  //возьмём текст
 <<<END

   Триста сорок восемь лет  шесть  месяцев и девятнадцать дней тому  назад
парижане проснулись под  перезвон всех колоколов, которые неистовствовали за
тремя оградами: Сите, Университетской стороны и Города.
     Между тем день  6 января  1482 года отнюдь не являлся  датой, о которой
могла бы хранить  память история. Ничего  примечательного не было в событии,
которое с самого утра привело в такое движение  и колокола и горожан Парижа.
Это не  был ни штурм пикардийцев  или  бургундцев, ни процессия с мощами, ни
бунт  школяров,  ни  въезд  "нашего  грозного  властелина короля",  ни  даже
достойная внимания казнь воров и воровок на  виселице по приговору парижской
юстиции. Это не было также столь частое в XV веке прибытие какоголибо пестро
разодетого и  разукрашенного плюмажами иноземного  посольства.  Не прошло  и
двух дней, как последнее из них -- это были фландрские послы, уполномоченные
заключить брак между дофином и Маргаритой Фландрской, -- вступило в Париж, к
великой  досаде кардинала  Бурбонского,  который, в угоду королю, должен был
скрепя сердце принимать неотесанную толпу фламандских бургомистров и угощать
их в своем  Бурбонском дворце представлением "прекрасной моралитэ,  шутливой
сатиры  и  фарса",  пока   проливной  дождь  заливал  его  роскошные  ковры,
разостланные у входа во дворец.
     Тем событием, которое  6 января "взволновало всю парижскую  чернь", как
говорит  Жеан  де  Труа, -- было  празднество,  объединявшее  с незапамятных
времен праздник Крещения с праздником шутов.
     В этот день на Гревской  площади зажигались потешные  огни,  у Бракской
часовни  происходила  церемония  посадки  майского деревца, в здании  Дворца
правосудия давалась  мистерия.  Об этом еще накануне  возвестили  при звуках
труб  на всех перекрестках глашатаи парижского прево, разодетые в щегольские
полукафтанья из лилового камлота с большими белыми крестами на груди.
     Заперев  двери домов и лавок,  толпы  горожан и горожанок с самого утра
потянулись  отовсюду  к упомянутым местам. Одни решили  отдать  предпочтение
потешным огням, другие  --  майскому дереву, третьи -- мистерии.  Впрочем, к
чести  исконного  здравого смысла  парижских  зевак,  следует  признать, что
большая  часть толпы направилась к  потешным  огням,  вполне уместным в  это
время года, другие -- смотреть мистерию в хорошо  защищенной от  холода зале
Дворца правосудия; а бедному, жалкому, еще  не  расцветшему майскому деревцу
все  любопытные единодушно предоставили зябнуть  в одиночестве под январским
небом, на кладбище Бракской часовни.
     Народ больше всего теснился  в проходах Дворца правосудия, так как было
известно,  что  прибывшие   третьего  дня   фландрские   послы  намеревались
присутствовать на представлении мистерии  и на избрании  папы шутов, которое
также должно было состояться в большой зале Дворца.
     Нелегко было пробраться в этот день  в большую  залу, считавшуюся в  то
время самым обширным закрытым помещением на свете. (Правда, Соваль тогда еще
не  обмерил  громадную залу  в  замке Монтаржи.) Запруженная народом площадь
перед  Дворцом правосудия представлялась зрителям, глядевшим на нее из окон,
морем, куда  пять или шесть  улиц, подобно устьям  рек, непрерывно извергали
все новые потоки голов. Непрестанно возрастая, эти людские волны разбивались
об  углы  домов,  выступавшие  то  тут,  то  там,  подобно  высоким  мысам в
неправильном водоеме площади.
     Посредине высокого готического  [2] фасада Дворца правосудия находилась
главная лестница, по которой  безостановочно поднимался и спускался  людской
поток; расколовшись ниже,  на  промежуточной площадке,  надвое, он  широкими
волнами разливался  по двум боковым  спускам;  эта главная лестница,  как бы
непрерывно струясь, сбегала  на площадь, подобно водопаду, низвергающемуся в
озеро.  Крик, смех,  топот  ног  производили страшный шум  и гам.  Время  от
времени этот шум и гам усиливался: течение, несшее толпу к главному крыльцу,
поворачивало вспять и, крутясь, образовывало водовороты.  Причиной тому были
либо стрелок,  давший комунибудь  тумака, либо  лягавшаяся лошадь начальника
городской  стражи, водворявшего  порядок;  эта  милая  традиция,  завещанная
парижским прево  конетаблям,  перешла от  конетаблей по наследству  к конной
страже, а от нее к нынешней жандармерии Парижа.
     В  дверях, в  окнах,  в слуховых оконцах, на крышах домов кишели тысячи
благодушных, безмятежных  и почтенных горожан, спокойно глазевших на Дворец,
глазевших  на  толпу  и  ничего  более  не  желавших,  ибо  многие  парижане
довольствуются  зрелищем  самих  зрителей, и даже стена, за которой что-либо
происходит, уже представляет для них предмет, достойный любопытства.
     Если бы нам, живущим в  1830 году, дано было мысленно вмешаться в толпу
парижан XV века и, получая со всех сторон пинки, толчки, -- прилагая крайние
усилия,  чтобы не упасть, проникнуть вместе с ней  в  обширную  залу Дворца,
казавшуюся   в  день  6   января   1482   года  такой  тесной,  то  зрелище,
представившееся  нашим  глазам,   не  лишено  было  бы   занимательности   и
очарования; нас  окружили  бы вещи  столь старинные, что они для нас были бы
полны новизны.
     Если  читатель  согласен, мы попытаемся хотя  бы мысленно воссоздать то
впечатление, которое  он испытал бы, перешагнув вместе с нами порог обширной
залы и очутившись среди толпы, одетой в хламиды, полукафтанья и безрукавки.
     Прежде  всего  мы  были  бы оглушены и ослеплены. Над  нашими  головами

END;

  //для начала нужен массив с номераминужных букв

//напишем функцию которая будет принимать строку и букву,а возвращать массив позициями этой буквы

 function one($str,$let){
         $pos=0;
         while($num=strpos ($str,$let,$pos) or $i++>10 ){
         $otvet[]=$num;
         $pos=$num+1;
                 }
         return  $otvet;
        }
//далее нам нужна не одно буква а все заданные


function shake($text,$all,$ver){
         foreach ($all as $k=>$v){
                  foreach (one($text,$k) as $v1){
                  $text=substr_replace ($text,$v, $v1,1);  //вот эту строку нужно доделать
                          }



         }
         return  $text;
         }

 /*!!!!!!ПРИМЕР РАБОТЫ!!!!!!!!!*/
         $zamena=array('а'=>'!!!!') ;

         echo shake($textQ,$zamena,20);

?>

Автор: Всемогущий 11.5.2007, 09:30
Код

if((rand (0,1000)-$ver*10)<0)$text=substr_replace ($text,$v, $v1,1);  


Добавлено через 3 минуты и 13 секунд
работает(просто заново скопировал все функции с переделанной строкой)


Код

  //для начала нужен массив с номераминужных букв

//напишем функцию которая будет принимать строку и букву,а возвращать массив позициями этой буквы

 function one($str,$let){
         $pos=0;
         while($num=strpos ($str,$let,$pos) or $i++>10 ){
         $otvet[]=$num;
         $pos=$num+1;
                 }
         return  $otvet;
        }
//далее нам нужна не одно буква а все заданные


function shake($text,$all,$ver){
         foreach ($all as $k=>$v){
                  foreach (one($text,$k) as $v1){
                  if((rand (0,1000)-$ver*10)<0)$text=substr_replace ($text,$v, $v1,1);   //вот эту строку нужно доделать
                          }



         }
         return  $text;
         }

 /*!!!!!!ПРИМЕР РАБОТЫ!!!!!!!!!*/
         $zamena=array('а'=>'!!!!') ;

         echo shake($textQ,$zamena,20);


Автор: -=Ustas=- 11.5.2007, 09:39
Цитата(tolik777 @  11.5.2007,  08:15 Найти цитируемый пост)
Есть текст. В нем нужно к примеру 10-20% букв "у" заменить на "u", буквы "л" на "l".

Странная задача вообще-то, не могу даже представить для чего это нужно.
Лично я бы сделал так
1. Находим все искомые символы "у"
2. Берем их количество в размере 10-20%
3. Затем от этого количества делаем замену с помощью preg_replace, используюя параметр limit, который равен 10-20%

Автор: Всемогущий 11.5.2007, 09:41
Цитата(-=Ustas=- @  11.5.2007,  11:39 Найти цитируемый пост)
3. Затем от этого количества делаем замену с помощью preg_replace, используюя параметр limit, который равен 10-20%

Да,но preg_replace заменит первые limit символов .А если вразброс?

Автор: SelenIT 11.5.2007, 09:45
Я бы использовал preg_replace_callback, а в качестве callback-функции - ту самую "условную заменялку по рандому"...

Автор: Всемогущий 11.5.2007, 09:52
Цитата(SelenIT @  11.5.2007,  11:45 Найти цитируемый пост)
Я бы использовал preg_replace_callback, а в качестве callback-функции - ту самую "условную заменялку по рандому"...

Можно прмерчик?

Автор: tolik777 14.5.2007, 14:54
Что то не работай этот код. Ругается на строку:  foreach (one($text,$k) as $v1){
Warning: Invalid argument supplied for foreach() in

Автор: SelenIT 19.5.2007, 22:42
Цитата(Всемогущий @  11.5.2007,  09:52 Найти цитируемый пост)
Можно прмерчик?

Сорри за задержку;), вот он:
Код

// $textQ можно взять из примера выше

function random_replace($a) {
   $repl = array('у'=>'u', 'л'=>'l');
   return (20 > mt_rand(0,100) ? $repl[$a[0]] : $a[0]);
}

echo '<pre>'.preg_replace_callback('/[ул]/', 'random_replace', $textQ).'</pre>';

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