Tein tällaisen PHP-koodin:
<?php $_POST['n'] = 5; $n = $_POST['n']; $luku = '111222333'; preg_replace_callback('/(\d)\1*/', function($v) { foreach ($v as $w) { echo $w . "\n"; } }, $luku);
Se tulostaa seuraavan tekstin:
111 1 222 2 333 3
Koodin pitäisi kuitenkin tulostaa:
111 222 333
Ongelma on se, että säännöllisen lausekkeen osan (\d)
tulisi periaatteessa olla (?:\d)
, mutta silloin takaisinviittaus ei toimi.
Miten estän turhat matchit niin, että takaisinviittaus toimii? Voisin tietenkin käydä taulukosta $v
läpi vain parittomat elementit, mutta olisiko parempaa ratkaisua?
Jännä kysymys.
Kertoisitko vähän tarkemmin, mitä olet tekemässä? Tästä esimerkistä on vähän vaikea sanoa, mikä olisi paras ratkaisu. Mitä jos vain käyttäisit arvoa $v[0]
?
<?php $luku = '111222333'; $str = preg_replace_callback('/(\d)\1*/', function($v) { echo $v[0] . "\n"; return "<" . $v[0] . ">"; }, $luku); echo $str . "\n";
Tulostus:
111 222 333 <111><222><333>
Kyseessä on keskeneräinen ratkaisu PHP-haasteen tähtävään 31: Hauska lukujono.
Ratkaisin tehtävän seuraavasti:
<?php $n = $_POST['n']; $luku = '1'; for ($i = 1; $i < $n; ++$i) { $luku = preg_replace_callback('/(\d)\1*/', function($v) { for ($i = 0; $i < count($v); $i += 2) { return strlen($v[$i]) . $v[$i][0]; } }, $luku); } echo $luku;
Silmukassa käydään siis läpi vain taulukon parittomat elementit.
Edelleen kiinnostaa, jos parempaa ratkaisua on tarjolla.
Lisäys:
Unohdin, millaisen taulukon preg_replace_callback
funktiolle antaa. Tosiaan vain indeksi 0
on tässä tapauksessa tarpeellinen, ja muut kuuluu jättää vain huomiotta. Ratkaisuksi tuli siis tämä:
<?php $n = $_POST['n']; $luku = '1'; for ($i = 1; $i < $n; ++$i) { $luku = preg_replace_callback('/(\d)\1*/', function($v) { return strlen($v[0]) . $v[0][0]; }, $luku); } echo $luku;
Idea on melko lähellä viimeistä malliratkaisua, joten olen sikäli tyytyväinen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.