Autor Zpráva
snazimse
Profil
Zdravím,

zkoumal, jsem v manuálu podrobněji funkci str_replace.

A našel jsem tam takový příklad.Když nahrazujeme jedno pole druhým polem stringů.

Nějak jsem vůbec nepochopil, proč tohle zrovna funguje, tak jak funguje.
Z logiky věci, bych čekal, že se jedno pole bude nahrazovat druhým od počátku.

Tzn hodnota s indexem 1 z prvního pole se nahradí za hodnotu s indexem 1 z druhého pole.
Ale není to tak, vždy se nahrazuje ta poslední.

Ale nechápu proč, rozumím jako tomu co říkají ale nechápu to.
Napíšou, výstup je F ,protože A je nahrazeno B, když B je nahrazeno s C, atd.

Ale tomu prostě fakt nerozumím, ať přemýšlím jak chci. Může mi to prosím někdo vysvětlit ten mechanismus?

Děkuji všem velmi!

// Outputs F because A is replaced with B, then B is replaced with C, and so on...
// Finally E is replaced with F, because of left to right replacements.
$search  = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'A';
echo str_replace($search, $replace, $subject);

// Outputs: apearpearle pear
// For the same reason mentioned above
$letters = array('a', 'p');
$fruit   = array('apple', 'pear');
$text    = 'a p';
$output  = str_replace($letters, $fruit, $text);
echo $output;

PS: Je mi z toho akorát zřejmé, že se to pořád posouvá, ale stejně mi to nedává moc smysl.
Jan Tvrdík
Profil
snazimse:
Jistě to nevím, ale řekl bych, že to první lze ekvivalentně napsat takto:

$search  = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'A';

foreach ($search as $key => $val) {
    $subject = str_replace($search[$key], $replace[$key], $subject);
}

echo $subject;

Je to jasnější?
Joker
Profil
snazimse:
Možná je na tom nejasné tohle: V každém kroku se nahrazuje v aktuálním řetězci, ne v tom, který byl na začátku.

Takže:
str_replace(array('A', 'B', 'C', 'D', 'E'), array('B', 'C', 'D', 'E', 'F'), "Ahoj");
Kroky:
1. V "Ahoj" nahradí 'A' na 'B' a vznikne "Bhoj".
2. V "Bhoj" se nahradí 'B' na 'C', vznikne "Choj".
…analogicky…
5. V "Ehoj" ae nahradí 'E' na 'F' a vznikne "Fhoj".

Kdyby se místo toho dělalo str_replace(array('A', 'B', '*', 'D', 'E'), array('B', 'C', 'D', 'E', 'F'), "Ahoj");, vznikne "Choj", protože se ten řetěz nahrazování přeruší.
juriad
Profil
Jan Tvrdík:
Ano, je tomu tak: gcov.php.net/PHP_5_4/lcov_html/ext/standard/string.c.gcov.php
Na řádku 3921 se rozhoduje podle toho, zda je parametr $search pole. Je-li, tak v cyklu (3936) provádí to samé nahrazení jako v případě, když je $search string.
snazimse
Profil
Jan Tvrdík, Joker, juriad:

Ano už je mi to jasné, děkuji moc nicméně mi to nedává moc smysl, k čemu to je dobré, k čemu bych to jako měl využít ,aby mi to vracelo vždy poslední index?

A s tím vystává otázka, když budu chtít, to udělat, tak jak by mi to dávalo smysl, první index s prvním indexem,
pěkně popořadě? A nahrazovat stejně, tak to si musím naprogramovat sám?

Anebo je na to nějaká základní funkce už v phpčku? Aby se mi to pěkně nahrazovalo jedno pole druhým polem postupně?

Děkuji!
juriad
Profil
snazimse:
To to přesně dělá. V dokumentaci jen ukazují extrémní případ, který je zajímavý z pohledu teorie. Pokud budeš chtít přepsat kočku za psa a rybu za papouška, bude se to chovat přesně tak, jak čekáš.

Ale kdybys chtěla přepsat kočku na psa a psa na kočku, budeš mít problém:
echo str_replace(array('kocka', 'pes'), array('pes', 'kocka'), 'pes'); # vypíše kocka
echo str_replace(array('kocka', 'pes'), array('pes', 'kocka'), 'kocka'); # vypíše kocka
snazimse
Profil
juriad:

No přijde mi to podivný já nevím, teda jak ta funkce jako přímo pracuje se stringem vše ok ,ale to pole,
trochu jsem to testoval. Jak to jako celé funguje při práci s polem, takže ,že to vyhodí ten konečný výsledek, jako první co najde?
Když má více možností nahrazení v poli?

Nebo jako poslední, když pracuje s polem? Jak s ním pracuje? Přijde mi to takové dost neočekávané.

Tohle např vrací pes echo str_replace(array('kocka', 'necojineho'), array('pes', 'kocka'), 'kocka');

To zjistil, že kocka nemůže být nahrazena kocka, a proto vybral pes?

Děkuji.
juriad
Profil
snazimse:
Moc o tom přemýšlíš. Zapomeň na to, že je to pole a snažíš se vybrat, co by šlo nahradit. Skrz ten řetězec se neprochází jednou a nehledá nejlepší nahrazení, ale prochází se ten řetězec délka-pole-krát.

Přečti si znovu zdroják v [#2]. Napřed všude nahradí první za první, pak druhé za druhé, pak třetí za třetí atd. Přičemž při druhém nahrazování nahrazuje v řetězci vzniklém pro tom prvním; ve třetím pracuje s řetězcem pro prvních dvou nahrazeních atd.

To je důvod, proč se při prvním nahrazení nahradí kočku za psa. Pak začne druhé nahrazení, to se stará jen o psa, kterého tam najde a nahradí jej za kočku. Ten pes tam vznikl jako důsledek prvního nahrazení.

Ten přiklad v [#6] je funkčně stejný jako toto (bez polí):
echo str_replace('pes', 'kocka', str_replace('kocka', 'pes', 'pes')); # vypíše kocka
echo str_replace('pes', 'kocka', str_replace('kocka', 'pes', 'kocka')); # vypíše kocka
snazimse
Profil
juriad:

Aha, takže jestli jsem pochopil správně, tak to funguje, jakoby rekurzivně, to znamená postupně se to zpracovává po sobě sekvenčně, takže když dám pole, způsobí postupné nahrazování jednoho výrazu dalším(nebo již nahrazeným).

Proto mi to nesedělo.

Chápu to teď správně?
juriad
Profil
snazimse:
Ano, přesně tak. Žádná inteligence za tím není.
snazimse
Profil
juriad:

Tak to je super. Děkuji ještě jednou za vysvětlení!

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: