[ deki_bg @ 13.11.2010. 18:37 ] @
Imam jedan niz sa 20 tak elemenata i jedan tekst.

Zelim da zamenim random tacke (.) i prazna mesta (' '), tj space
sa clanovima niza jedanim po jednim.

Znaci svi clanovi niza moraju biti iskorisceni ali ne da redom zamene sve tacke i prazna mesta vec random da neke preskoce a neke zamene.



Npr. ako je niz (1,2,3,4), a tekst:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer luctus pulvinar nisl in consequat. Integer nec ante id ligula tincidunt consequat.

Funkcija bi trebala da iskoristi sve elemente 1,2,3 i 4 i da ih stavi umesto neke tacke ili razmaka.


Lorem ipsum dolor1sit amet, consectetur adipiscing elit2 Integer luctus pulvinar nisl in3consequat. Integer nec ante id4ligula tincidunt consequat.


Da li neko ima ideju kako ovo da resim ?
[ vatri @ 13.11.2010. 19:19 ] @
Evo nesto brzinski - valjda si tako nesto trazio?

Code (php):

<?php

$reps = array('{rep1}','{rep2}','{rep3}','{rep4}','{rep5}','{rep6}','{rep7}');//replacements

$text = 'Lorem ipsum dolor1sit amet, consectetur adipiscing elit2
Integer luctus pulvinar nisl in3consequat. Integer nec ante id4ligula tincidunt consequat. '
;
$arrChar = str_split($text);

$ctr = array();//chars to replace
foreach($arrChar as $i=>$char)
{
     if($char == '.' or $char == ' ')
     {
          $ctr[$i] = $char;
     }
}

foreach($reps as $newVal)
{
     $itr = array_rand($ctr);//position of char to replace
     $arrChar[$itr] = $newVal;
}

$output = implode('',$arrChar);

echo 'Old text:<br><br>';
echo $text;
echo '<hr>';
echo 'New text:<br><br>';
echo $output;

?>
 
[ Nikola Poša @ 13.11.2010. 19:23 ] @
Veoma neobičan zadatak, al' vidi da li ti odgovara npr. ovako nešto:
Code:
$tekst = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Integer luctus pulvinar nisl in consequat. 
    Integer nec ante id ligula tincidunt consequat.';
    
function zamena_callback($matches)
{
    $zamena = array(1,2,3,4);

    return (string)$zamena[array_rand($zamena)];
}

$tekst = preg_replace_callback(
            "/(\.|\s)/",
            "zamena_callback",
            $tekst);
[ deki_bg @ 13.11.2010. 19:29 ] @
Hvala !

Prvo resenje nije iskoristilo sve elemente niza.

Drugo resenje koristi svaki od clanova niza vise od jednom, a trebalo bi maximum jednom da se pojavi svaki clan niza.
[ Nikola Poša @ 13.11.2010. 19:33 ] @
Ispravio sam moj prethodni post pre koji minut, jer sam na pogrešan način iskoristio funkciju array_rand(). Ona, u slučaju da drugi parametar koji joj se prosleđuje ima vrednost 1 (a ima po default-u), vraća indeks random člana prosleđenog niza, a ne vrednost.

Ovako bi trebala da izgleda return linija te callback funkcije:
Code:
return (string)$zamena[array_rand($zamena)];
[ vatri @ 13.11.2010. 19:35 ] @
Da zaboravio sam: moras sacuvati u jedan array kljuceve koju su zamjenjeni.
Gledaj dio u sledecem bloku:

foreach($reps as $newVal)
{
// - ovde dodaj array u koji ces cuvati kljuceve koji se zamjene i
// - provjeriti da li trenutni kljuc postoji u tom array-u
// - tek onda uraditi zamjenu
}
[ deki_bg @ 13.11.2010. 19:37 ] @
@Nikola Poša, I dalje vraca ovo:

Lorem1ipsum4dolor3sit2amet,4consectetur1adipiscing3elit3411113Integer3luctus2pulvinar4nisl4in1consequat4444114Integer1nec3ante4id2ligula2tincidunt4consequat1

Tj svi clanovi niza se ponavljaju mnogo puta.
[ Nikola Poša @ 13.11.2010. 19:41 ] @
Mislim da je ovo pravo rešenje:
Code:
$zamena = array(1,2,3,4);
$tekst = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Integer luctus pulvinar nisl in consequat. 
    Integer nec ante id ligula tincidunt consequat.';
    
for($i=0; $i<=strlen($tekst); $i++) {
    if (($tekst{$i} == ' ' || $tekst{$i} == '.')
        && array_rand(array(1,2,3)) == 0
        && !empty($zamena)
    ) {
        $randKey = array_rand($zamena);
        $rand = (string)$zamena[$randKey];
        
        $tekst{$i} = $rand;
        unset($zamena[$randKey]);
    }
}

echo $tekst;

Obrati pažnju na taj drugi uslov u if-u unutar foreach-a. Njime povećavaš/smanjuješ nasumičnost zamene.
[ deki_bg @ 13.11.2010. 19:47 ] @
Notice: Uninitialized string offset: 157 in index.php on line 19
[ Nikola Poša @ 13.11.2010. 19:49 ] @
Umesto $i <= strlen($tekst) stavi $i < strlen($tekst).
[ deki_bg @ 13.11.2010. 19:49 ] @
Takodje kada zamenim clanove niza sa necim drugim
$zamena = array("WWW1","WWW2","WWW3");
Ovo vise ne radi.
Brojevi u nizu su bili samo primer.
[ Nikola Poša @ 13.11.2010. 19:58 ] @
E pa što ne reče odma' da treba da menjaš sa nečim što ima više od 1 karaktera...

Probaj ovo:
Code:
$zamena = array("WWW1","WWW2","WWW3");
$tekst = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Integer luctus pulvinar nisl in consequat. 
    Integer nec ante id ligula tincidunt consequat.';
    
echo 'Pre: ' . $tekst . '<br /><br />';

$karakteri = str_split($tekst);
foreach ($karakteri as $i=>$karakter) {
    if (($karakter == ' ' || $karakter == '.')
        && array_rand(array(1,2,3)) == 0
        && !empty($zamena)
    ) {
        $randKey = array_rand($zamena);
        $rand = (string)$zamena[$randKey];
        
        $karakteri[$i] = $rand;
        unset($zamena[$randKey]);
    }
}

$tekst = implode('', $karakteri);

echo 'Posle: ' . $tekst;
[ deki_bg @ 13.11.2010. 20:02 ] @
Genije si !
Hvala puno !

Saljem ti email preko tvog sajta.
[ notnowjohn @ 13.11.2010. 20:54 ] @
Moze to i ovako. Slicno je, ali ima par sitnih razlika.

Code (php):
$reps = array(1,2,3,4);
$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer luctus pulvinar nisl in consequat. Integer nec ante id ligula tincidunt consequat.';
$find = array('.', ' ');
$textArr = str_split($text);

$chArr = array();
foreach ($textArr AS $key=>$value) {
     if (in_array($value, $find)) $chArr[$key] = $value;
}
unset($textArr);

//za svaki reps
/*foreach ($reps AS $rep) {
     $rand = array_rand($chArr);
     $text[$rand] = $rep;
     unset($chArr[$rand]);
}*/


//ili
//za svaki find
/*while (!empty($chArr)) {
     $rand = array_rand($chArr);
     $text[$rand] = array_rand($reps);
     unset($chArr[$rand]);
}*/


echo $text;
[ deki_bg @ 13.11.2010. 21:13 ] @
Zbog str_split funckije ovo jedino radi ako ocu da zamenim samo jedan karakter, a meni u principu treba da celu rec zamenim tj grupu karatkera.
Tj ne samo tacku vec tacku koja je ogruzena razmakom sa obe strane:
" . "
ili rec " the " koja opet ima sa obe strane praznog prostora.

[ deki_bg @ 13.11.2010. 21:36 ] @
Resio sam sa explode u nikolinom kodu.
Medjutim u njegovom kodu se i dalje ne iskoriste svi elementi niza.
Probao sam sa mnogo vecim textom i 20 elemenata niza i samo 5 ili 6 bude iskorisceno, a ja bi hteo sve da iskoristim.
[ Nikola Poša @ 13.11.2010. 21:45 ] @
To je zato što je ovaj drugi uslov array_rand(array(1,2,3)) == 0 mnogo strog... Probaj da staviš samo niz sa dva elementa, npr. array_rand(array(1,2)) == 0. Ali svejedno, opet postoji šansa da ta nasumičnost, u tom slučaju upotreba array_rand, nikad neće vratiti nulti indeks, bez obzira što može da bira samo između dve vrednosti.
[ notnowjohn @ 13.11.2010. 21:49 ] @
Citat:
deki_bg: Resio sam sa explode u nikolinom kodu.
Medjutim u njegovom kodu se i dalje ne iskoriste svi elementi niza.
Probao sam sa mnogo vecim textom i 20 elemenata niza i samo 5 ili 6 bude iskorisceno, a ja bi hteo sve da iskoristim.


Elementi kog niza? Ono sto trazis ili sa cime radis replace?
Trebao si navesti jedan konkretan primer koji objedinjuje sve potrebe.

Recimo da imas $reps, $find, $text. Reps je za replace, find trazis (i jedno i drugo je array) a text je string i sadrzi text koji se obradjuje. Ti hoces da iskoristis sve reps ili sve find u tekstu (slucajnim izborom)? I hoces da reps i find elementi mogu da budu duzi od jendog karaktera? Jel to?
Ako sam dobro sumrirao kazi da ne kucam bez veze. :)
[ notnowjohn @ 13.11.2010. 22:47 ] @
Evo ti i ova varijanta. Ako je negde u sintaksi greska, valjda ces znati da u uklonis, nemam vremena da proveravam, a i dugo sam cekao da odgovoris.
Dve opcije imas, da izmeni sve sto pronadje (sa random reps) ili da iskoristi sve reps a menja nasumicno izabrane delove koji se poklapaju sa nekim od elemenata find.

Code (php):
$find = array('foo', 'bar', 'baz');
$reps = array('fooBar', 'fooBaz' , 'barFoo');
$text = 'foo bar baz split php preg foo regex bar split foo';

$textArr = preg_split("/(".implode("|", $find).")/", $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
unset($text);

$matches = array();
foreach ($textArr AS $key=>$value) {
     if (in_array($value, $find)) $matches[$key] = $value;
}

//za svaki reps
/*foreach ($reps AS $rep) {
     $rand = array_rand($matches);
     $textArr[$rand] = $rep;
     unset($matches[$rand]);
}*/


//za svaki find
/*while (!empty($matches)) {
     $rand = array_rand($matches);
     $textArr[$rand] = $reps[array_rand($reps)];
     unset($matches[$rand]);
}*/



echo implode('', $textArr);

[ vatri @ 14.11.2010. 00:05 ] @
Jbg, ja ako sam dobro skontao sta ti hoces, onda ovo mora raditi:

Code (php):

<?php

$reps = array('{rep1}','{rep2}','{rep3}','{rep4}','{rep5}','{rep6}','{rep7}');//replacements

$text = 'Lorem ipsum dolor1sit amet, consectetur adipiscing elit2
Integer luctus pulvinar nisl in3consequat. Integer nec ante id4ligula tincidunt consequat. '
;
$arrChar = str_split($text);

$ctr = array();//chars to replace
foreach($arrChar as $i=>$char)
{
     if($char == '.' or $char == ' ')
     {
          $ctr[$i] = $char;
     }
}

$used = array();
foreach($reps as $newVal)
{
     $itr = array_rand($ctr);//position of char to replace
     while(in_array($itr, $used))
     {
          $itr = array_rand($ctr);
     }
     $arrChar[$itr] = $newVal;
     $used[] = $itr;
}

$output = implode('',$arrChar);

echo 'Old text:<br><br>';
echo $text;
echo '<hr>';
echo 'New text:<br><br>';
echo $output;

?>
 


Ako ti treba mozes zamjeniti liniju:

if($char == '.' or $char == ' ')

sa

if( in_array($char,$chars_to_replace))...

...gdje u chars_to_replace niz uneses karaktere koje zelis da zamjenis.