« 1 2 »
Autor Zpráva
Jack06
Profil
Zdravím, potřeboval bych nahrazovat slova v textu. Ve foreach budu mít vždy jedno slovo, které potřebuji nahradit. Ovšem to slovo mohu nahradit jen v případě, že není v tagu jako takovém. Popíšu:

Chci nahrazovat slovo AHOJ (na velikosti písmen by nemělo záležet:

<div>
Ahoj pepo, posílám ti pozdrav ahoj z dovolené
<img alt="AHOJ">
</div>

potřebuji aby se mi toto upravilo následovně:

<div>
Ahoj&nbsp;pepo, posílám ti pozdrav ahoj&nbsp;z dovolené
<img alt="AHOJ">
</div>

Bohužel jsem nepřišel na to, jak omezit to, aby se ty slova nenahrazovali, když jsou v <.. kdekoli zde ..>
Předem moc děkuji
ShiraNai7
Profil
Lze to udělat, ale celkem složitou funkcí. Regulárama bych do toho nešel, s tím nemáš moc šanci. Sepsal jsem na to funkci.
Ukázka:

// kod ve kterem chceme nahrazovat
$code = '<div>
Ahoj pepo, posílám ti pozdrav ahoj z dovolené
<img alt="AHOJ">
</div>';

// pouziti funkce
echo formatujSlova($code, array('ahoj'));

Výsledek ukázky je:
<div>
Ahoj&nbsp;pepo, posílám ti pozdrav ahoj&nbsp;z dovolené
<img alt="AHOJ"/></div>

A zde je zmiňovaná funkce (pro PHP 5+).
První argument je HTML kód, druhý pole se slovy, za které se má přidat &nbsp;.
&nbsp; se přidává, jen když je za slovem whitespace.

function formatujSlova($code, array $wordList)
{

    // priprava dokumentu
    $doc = new DOMDocument;
    $doc->loadHTML("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html><html><head></head><body>{$code}</body></html>");
    //echo $doc->saveXML(); die;
    $xpath = new DOMXPath($doc);

    // priprava regularu
    $wordCounter = 0;
    $wordPattern = '';
    foreach($wordList as $word) {
        if(0 !== $wordCounter) $wordPattern .= '|';
        $wordPattern .= preg_quote($word);
        ++$wordCounter;
    }

    // nahrazeni v text nodech
    foreach($xpath->query('//text()') as $textNode) {

        $parent = $textNode->parentNode;

        // zpracovat slova
        if(0 === preg_match_all('/('.$wordPattern.')\\s/mi', $textNode->wholeText, $words, PREG_OFFSET_CAPTURE)) {
            continue;
        }
        $lastOffset = 0;
        $newNodes = array();
        foreach($words[0] as $i => $word) {
            $newNodes[] = new DOMText(substr($textNode->wholeText, $lastOffset, $word[1] - $lastOffset).$words[1][$i][0]);
            $newNodes[] = new DOMEntityReference('nbsp');
            $lastOffset = $word[1] + strlen($word[0]);
        }
        $newNodes[] = new DOMText(substr($textNode->wholeText, $lastOffset));

        // vlozit nove casti
        for($i = 0; isset($newNodes[$i]); ++$i) {
            $parent->insertBefore($newNodes[$i], $textNode);
        }

        // smazat stary text
        $parent->removeChild(
            $textNode
        );

    }

    // ziskat vysledek
    $out = '';
    foreach($xpath->query('/html/body')->item(0)->childNodes as $item) {
        $out .= $doc->saveXML($item);
    }
    return $out;

}
Jack06
Profil
Tyjo až tak složitě jo? To nelze nějak jednodušeji přes regulární výrazy??
ShiraNai7
Profil
Ne. Nemáš šanci regulárem ošetřit všechny případy, které můžou nastat. Moje funkce provádí nahrazení skutečně pouze na textových částech HTML kódu.
Jack06
Profil
Jen je problém s tím, že to po parsování odstraní řádky.. což není dobře.
+ by mě zajímalo co přepsat, abych tam mohl přidávat ještě ty nbps před slova. Tedy je možné, že nějaké slovo bude mít nbps za slovem, ale i před slovem.
ShiraNai7
Profil
Inspiraci máš, stačí upravit. Pro přidávání před slova by se musel přidat další argument (nebo zkomplikovat ten druhý), upravit regulár a před první $newNodes[] přidat další podmíněný řádek, který dělá entitu. Víc už nemůžu pomoct, jelikož můj limit zbytečné práce byl vyčerpán :)

edit: příčinou "odstraňování" řádku si nejsem jistý, ale odstraní se pouze prázdné whitespace
Jack06
Profil
S DOM objektama jsem nikdy nedělal. Vím proč to maže mezery, ale nevím kde to hledat. Nyní je to tak, že to prostě maže jeden znak (mezera nebo odřádkování) za slovem, které nahrazuje, když napíšu to slovo bez mezery a hned ho odřádkuji, tak smaže to odřádkování. Nejspíše by stačilo někde podmínit, že jen mezeru by to mohlo mazat.

+, když text obsahuje &, tak se přestane parsovat
ShiraNai7
Profil
Jack06:
Nejspíše by stačilo někde podmínit, že jen mezeru by to mohlo mazat.
Řádek 25 nahraď tímto:
       if(0 === preg_match_all('/('.$wordPattern.')\ /mi', $textNode->wholeText, $words, PREG_OFFSET_CAPTURE)) {

Místo \s jsem tam dal mezeru, tj. nemělo by to brát konce řádku.
Jack06
Profil
ShiraNai7:
Já to nahradil zatím [ |$], jen teda viz jsem dopsal:

plus to bere konce slov...
Na parsování mám slovo "ze" a když mám výraz pařeze, tak to za to hodí taky &nbsp;
ShiraNai7
Profil
Jack06:
Jak jsem psal - je to jen základ funkce. Upravit si ji můžeš dle libosti :)
Šlo by na začátek patternu (před závorku) přidat něco jako [^a-zA-Z] nebo [. ,;] aby to nebralo slova od poloviny.
Jack06
Profil
ShiraNai7:
kurde to když udělám, tak to odstraňuje i mezery před textem :-D
ShiraNai7
Profil
Jó musí se to trošku přepsat, něco zkusím.
Jack06
Profil
No zatím jsem na tom nevykoumal nic, když někde něco omezím, tak mě to někde něco usekne.

Když je & v textu, tak to přestane parsovat ještě (se znakama + a možná i dalšíma to taky blbne, smaže to ten znak +)
ShiraNai7
Profil
Jack06:
Zkus upravenou funkci. Nepoužívá reguláry ale vlastní detekční "algoritmus":

<?php

function formatujSlova($code, array $wordList)
{

    // priprava dokumentu
    $doc = new DOMDocument;
    $doc->loadHTML("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html><html><head></head><body>{$code}</body></html>");
    $xpath = new DOMXPath($doc);

    // priprava slov
    for($i = 0; isset($wordList[$i]); ++$i) {
        $wordList[$i] = array($wordList[$i][0], $wordList[$i], strlen($wordList[$i]));
    }

    // nahrazeni v text nodech
    foreach($xpath->query('//text()') as $textNode) {

        $parent = $textNode->parentNode;

        // zpracovat text
        $newNodes = array();
        $lastOffset = 0;
        $char = null;
        $lastChar = null;
        for($i = 0; isset($textNode->wholeText[$i]); ++$i) {

            // ziskat znak
            $lastChar = $char;
            $char = $textNode->wholeText[$i];

            // preskocit pokud minuly znak nebyl zacatek ci mezera
            if(null !== $lastChar && ' ' !== $lastChar) {
                continue;
            }

            // detekovat slova
            for($ii = 0; isset($wordList[$ii]); ++$ii) {

                // test prvniho znaku slova
                if($char === $wordList[$ii][0]) {

                    // test ostatnich znaku
                    $offset = 0;
                    for($iii = $i; isset($wordList[$ii][1][$offset]); ++$iii) {
                        if($wordList[$ii][1][$offset] === $textNode->wholeText[$iii]) {

                            // znak ok
                            ++$offset;
                            if($offset === $wordList[$ii][2]) {

                                /* --- plna detekce slova --- */

                                // preskocit, pokud nasledujici znak neni konec ci mezera
                                ++$iii;
                                if(isset($textNode->wholeText[$iii]) && ' ' !== $textNode->wholeText[$iii]) {
                                    break;
                                }

                                // cast textu pred + slovo
                                $newNodes[] = new DOMText(
                                    substr($textNode->wholeText, $lastOffset, $i - $lastOffset)
                                    .$wordList[$ii][1]
                                );

                                // + &nbsp;
                                $newNodes[] = new DOMEntityReference('nbsp');

                                // aktualizovat posledni offset, konec
                                $lastOffset = $i + $wordList[$ii][2] + 1;
                                break;

                            }
                        } else {
                            // neplatny znak
                            break;
                        }
                    }

                }

            }

        }
        $newNodes[] = new DOMText(substr($textNode->wholeText, $lastOffset));

        // vlozit nove casti
        for($i = 0; isset($newNodes[$i]); ++$i) {
            $parent->insertBefore($newNodes[$i], $textNode);
        }

        // smazat stary text
        $parent->removeChild(
            $textNode
        );

    }

    // ziskat vysledek
    $out = '';
    foreach($xpath->query('/html/body')->item(0)->childNodes as $item) {
        $out .= $doc->saveXML($item);
    }
    return $out;

}
Jack06
Profil
No to už jde asi dobře, jen to stále dělá bordel, když je v textu + nebo &
ShiraNai7
Profil
Jack06:
Před $doc->loadHTML na začátku funkce přidej "@" (bez uvozovek). Samotný ampersand (&) v kódu je totiž technicky syntaktická chyba. S + atd nemám žádný problém.
Jack06
Profil
ShiraNai7:
+ mi to odstraní a místo něj mi to napíše mezeru
ShiraNai7
Profil
Jack06:
Dej mi ukázku kódu, kde ti to dělá.
Jack06
Profil
ShiraNai7:
Tak třeba tento text to rozhází:

<p>
<img alt="Peugeot vystavuje v Brně ekologické technologie" border="0" src="/media/deliacms/media/61/6199-fc8531.jpg" style="display: none;" /></p>
<p>
<a href="/media/deliacms/media/61/6194-4b9c43.jpg" onclick="window.open(this.href,'','resizable=yes,location=no,menubar=no,scrollbars=yes,status=no,toolbar=no,fullscreen=no,dependent=no,width=1054,height=504,status'); return false"><img alt="Peugeot vystavuje v Brně ekologické technologie" src="/media/deliacms/media/61/6192-0a076e.jpg" style="padding: 0 0 45px 15px; float: right;" /></a>
<b>Letos už podruhé vystaví společnost PEUGEOT ČESKÁ REPUBLIKA na brněnském výstavišti moderní technologie snižující dopad automobilů na životní prostředí. Po účasti na elektrotechnickém veletrhu AMPER 2012 se nyní chystá i na ENVIBRNO &amp; mezinárodní veletrh techniky pro tvorbu a ochranu životního prostředí, který se koná od 24. do 27. dubna 2012 v Brně. Souběžně probíhají i odborné veletrhy URBIS INVEST a URBIS TECHNOLOGIE.</b></p>
<p>
&nbsp;</p>
<p>
Vývoji technologií přispívajícím k&nbsp;ochraně životního prostředí věnuje značka Peugeot dlouhodobě značnou pozornost. Ty nejmodernější a nejúčinnější inovace z oblasti elektromobilů a hybridních vozů představí společnost PEUGEOT ČESKÁ REPUBLIKA návštěvníkům veletrhu ENVIBRNO a dalších souběžně probíhajících veletrhů.</p>
<p>Dva se rovná jedna + jedna</p>
<p>Na na na na+ na+</p>
ShiraNai7
Profil
Při tomto volání, kde $kod je ten, co jsi poskytl:
echo formatujSlova($kod, array('že', 'a', 'z', 'od', 'do', 'na'));

..dostanu:
<p>
<img alt="Peugeot vystavuje v Brně ekologické technologie" border="0" src="/media/deliacms/media/61/6199-fc8531.jpg" style="display: none;"/></p>
<p>
<a href="/media/deliacms/media/61/6194-4b9c43.jpg" onclick="window.open(this.href,'','resizable=yes,location=no,menubar=no,scrollbars=yes,status=no,toolbar=no,fullscreen=no,dependent=no,width=1054,height=504,status'); return false"><img alt="Peugeot vystavuje v Brně ekologické technologie" src="/media/deliacms/media/61/6192-0a076e.jpg" style="padding: 0 0 45px 15px; float: right;"/></a>
<b>Letos už podruhé vystaví společnost PEUGEOT ČESKÁ REPUBLIKA na&nbsp;brněnském výstavišti moderní technologie snižující dopad automobilů na&nbsp;životní prostředí. Po účasti na&nbsp;elektrotechnickém veletrhu AMPER 2012 se nyní chystá i na&nbsp;ENVIBRNO &amp; mezinárodní veletrh techniky pro tvorbu a&nbsp;ochranu životního prostředí, který se koná od&nbsp;24. do&nbsp;27. dubna 2012 v Brně. Souběžně probíhají i odborné veletrhy URBIS INVEST a&nbsp;URBIS TECHNOLOGIE.</b></p>
<p>
 </p>
<p>
Vývoji technologií přispívajícím k ochraně životního prostředí věnuje značka Peugeot dlouhodobě značnou pozornost. Ty nejmodernější a&nbsp;nejúčinnější inovace z&nbsp;oblasti elektromobilů a&nbsp;hybridních vozů představí společnost PEUGEOT ČESKÁ REPUBLIKA návštěvníkům veletrhu ENVIBRNO a&nbsp;dalších souběžně probíhajících veletrhů.</p>
<p>Dva se rovná jedna + jedna</p>
<p>Na na&nbsp;na&nbsp;na+ na+</p>

Nevidím problém. Mám PHP 5.3.5. Na čem to testuješ ty?
Jack06
Profil
ShiraNai7:
No nevím proč, ale mám utf-8 a brně mi to napíše jako Brn &# x11B;

+ aby to nerozlišovalo velikost písmen, to fungovalo ted nefunguje
+ když je nbsp; v textu, tak ho vyhodí - viz řádek 9

Jinak už asi v klidu
ShiraNai7
Profil
Jack06:
Tohle je case-insensitive verze (nebere ohled na velikost písmen), také už nepřevádí znaky na entity.
Každopádně zachování původních &nbsp; jsem nevyřešil, jelikož DOMDocument->loadHTML() nebere ohled na DOMDocument->substituteEntities = false. Pokud chceš mít za určitými slovy &nbsp;, tak je přidej do $wordListu.

<?php

function formatujSlova($code, array $wordList)
{

    // priprava dokumentu
    $doc = new DOMDocument;
    $doc->loadHTML("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body>{$code}</body></html>");
    $xpath = new DOMXPath($doc);

    // priprava slov
    for($i = 0; isset($wordList[$i]); ++$i) {
        $wordList[$i] = array($wordList[$i][0], $wordList[$i], strlen($wordList[$i]));
    }

    // nahrazeni v text nodech
    foreach($xpath->query('//text()') as $textNode) {

        $parent = $textNode->parentNode;
        $text = $textNode->wholeText;

        // zpracovat text
        $newNodes = array();
        $lastOffset = 0;
        $char = null;
        $lastChar = null;
        for($i = 0; isset($text[$i]); ++$i) {

            // ziskat znak
            $lastChar = $char;
            $char = $text[$i];

            // preskocit pokud minuly znak nebyl zacatek ci mezera
            if(null !== $lastChar && ' ' !== $lastChar) {
                continue;
            }

            // detekovat slova
            for($ii = 0; isset($wordList[$ii]); ++$ii) {

                // test prvniho znaku slova
                if(0 === strcasecmp($char, $wordList[$ii][0])) {

                    // test ostatnich znaku
                    $offset = 0;
                    for($iii = $i; isset($wordList[$ii][1][$offset]); ++$iii) {
                        if(0 === strcasecmp($wordList[$ii][1][$offset], $text[$iii])) {

                            // znak ok
                            ++$offset;
                            if($offset === $wordList[$ii][2]) {

                                /* --- plna detekce slova --- */

                                // preskocit, pokud nasledujici znak neni konec ci mezera
                                ++$iii;
                                if(isset($text[$iii]) && ' ' !== $text[$iii]) {
                                    break;
                                }

                                // cast textu pred + slovo
                                $newNodes[] = new DOMText(
                                    substr($text, $lastOffset, $i - $lastOffset + $wordList[$ii][2])
                                );

                                // + &nbsp;
                                $newNodes[] = new DOMEntityReference('nbsp');

                                // aktualizovat posledni offset, konec
                                $lastOffset = $i + $wordList[$ii][2] + 1;
                                break;

                            }
                        } else {
                            // neplatny znak
                            break;
                        }
                    }

                }

            }

        }
        $newNodes[] = new DOMText(substr($text, $lastOffset));

        // vlozit nove casti
        for($i = 0; isset($newNodes[$i]); ++$i) {
            $parent->insertBefore($newNodes[$i], $textNode);
        }

        // smazat stary text
        $parent->removeChild(
            $textNode
        );

    }

    // ziskat vysledek
    $out = '';
    foreach($xpath->query('/html/body')->item(0)->childNodes as $item) {
        $out .= $doc->saveXML($item);
    }
    return $out;

}
Jack06
Profil
ShiraNai7:
S tím nbsp jsem to udělal tak, že jsem si to úplně předem přes preg_replace přepsal na "bbcode" a nakonci si ho zase přepsal zpět.
Jinak se mi stále nedaří dostat ten nbsp před slovo. Moc se v tom algoritmu nevyznám abych věděl kde co přepsat aby to bralo místo za před.
ShiraNai7
Profil
Dole máš upravenou funkci. Přibyl nový argument, který určuje, kam se má &nbsp; přidávat. Pro každé slovo (na stejné pozici v poli) je možné (ale nepovinné) definovat mód jako jedno z čísel:

• 0 = přidat před (výchozí)
• 1 = přidat za
• 2 = přidat před i za

Přiklad použití:
<?php echo formatujSlova($kod, array('že', 'a', 'z', 'od', 'do', 'na'), array(0, 2, 2, 0, 0, 0));


Upravená funkce:

<?php
/**
 * Pridat &nbsp; za anebo pred slova
 *
 * Mozne hodnoty pro $wordModes (namisto XX):
 * -------------------------------------------
 * [0] pridat za slovo (vychozi)
 * [1] pridat pred slovo
 * [2] pridat za i pred slovo
 *
 * @param string $code html kod
 * @param array $wordList seznam slov, array('slovo1', 'slovo2', ...)
 * @param array $wordModes mod pridani &nbsp;, array(XX, XX, ...)
 * @return string
 */
function formatujSlova($code, array $wordList, array $wordModes = array())
{

    // priprava dokumentu
    $doc = new DOMDocument;
    $doc->loadHTML("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body>{$code}</body></html>");
    $xpath = new DOMXPath($doc);

    // priprava slov
    for($i = 0; isset($wordList[$i]); ++$i) {
        $wordList[$i] = array($wordList[$i][0], $wordList[$i], strlen($wordList[$i]));
    }

    // nahrazeni v text nodech
    foreach($xpath->query('//text()') as $textNode) {

        $parent = $textNode->parentNode;
        $text = $textNode->wholeText;

        // zpracovat text
        $newNodes = array();
        $lastOffset = 0;
        $char = null;
        $lastChar = null;
        for($i = 0; isset($text[$i]); ++$i) {

            // ziskat znak
            $lastChar = $char;
            $char = $text[$i];

            // preskocit pokud minuly znak nebyl zacatek ci mezera
            if(null !== $lastChar && ' ' !== $lastChar) {
                continue;
            }

            // detekovat slova
            for($ii = 0; isset($wordList[$ii]); ++$ii) {

                // test prvniho znaku slova
                if(0 === strcasecmp($char, $wordList[$ii][0])) {

                    // test ostatnich znaku
                    $offset = 0;
                    for($iii = $i; isset($wordList[$ii][1][$offset]); ++$iii) {
                        if(0 === strcasecmp($wordList[$ii][1][$offset], $text[$iii])) {

                            // znak ok
                            ++$offset;
                            if($offset === $wordList[$ii][2]) {

                                /* --- plna detekce slova --- */

                                // preskocit, pokud nasledujici znak neni konec ci mezera
                                ++$iii;
                                if(isset($text[$iii]) && ' ' !== $text[$iii]) {
                                    break;
                                }

                                $wordMode = (!isset($wordModes[$ii]) ? 0 : $wordModes[$ii]);

                                // cast textu pred + slovo
                                if(0 === $wordMode) {
                                    $newNodes[] = new DOMText(
                                        substr($text, $lastOffset, $i - $lastOffset + $wordList[$ii][2])
                                    );
                                } else {

                                    // cast textu pred
                                    $newNodes[] = new DOMText(
                                        substr($text, $lastOffset, $i - $lastOffset - 1)
                                    );

                                    // &nbsp; pred
                                    $newNodes[] = new DOMEntityReference('nbsp');

                                    // + slovo
                                    $newNodes[] = new DOMText(
                                        substr($text, $i, $wordList[$ii][2] + ((1 === $wordMode) ? 1 : 0))
                                    );

                                }

                                // &nbsp; za
                                if(1 !== $wordMode) {
                                    $newNodes[] = new DOMEntityReference('nbsp');
                                }

                                // aktualizovat posledni offset, konec
                                $lastOffset = $i + $wordList[$ii][2] + 1;
                                break;

                            }
                        } else {
                            // neplatny znak
                            break;
                        }
                    }

                }

            }

        }
        $newNodes[] = new DOMText(substr($text, $lastOffset));

        // vlozit nove casti
        for($i = 0; isset($newNodes[$i]); ++$i) {
            $parent->insertBefore($newNodes[$i], $textNode);
        }

        // smazat stary text
        $parent->removeChild(
            $textNode
        );

    }

    // ziskat vysledek
    $out = '';
    foreach($xpath->query('/html/body')->item(0)->childNodes as $item) {
        $out .= $doc->saveXML($item);
    }
    return $out;

}
Jack06
Profil
ShiraNai7:
Tak to má stále nějaký problém. Když si napíšu text:

Jsem ve státě COŽ republika
Jsem ve státě ČESKÁ republika
Jsem ve státě UŽ republika

a ve slovech k přepsání v db mám: česká, což, už .... tak to prostě nefunguje.
ShiraNai7
Profil
Jack06:
/**
 * Pridat &nbsp; za anebo pred slova
 *
 * Mozne hodnoty pro $wordModes (namisto XX):
 * -------------------------------------------
 * [0] pridat za slovo (vychozi)
 * [1] pridat pred slovo
 * [2] pridat za i pred slovo
 *
 * @param string $code html kod
 * @param array $wordList seznam slov, array('slovo1', 'slovo2', ...)
 * @param array $wordModes mod pridani &nbsp;, array(XX, XX, ...)
 * @return string
 */
function formatujSlova($code, array $wordList, array $wordModes = array())
{

    // priprava dokumentu
    $doc = new DOMDocument;
    $doc->loadHTML("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body>{$code}</body></html>");
    $xpath = new DOMXPath($doc);

    // priprava slov
    for($i = 0; isset($wordList[$i]); ++$i) {
        $wordList[$i] = array($wordList[$i][0], $wordList[$i], strlen($wordList[$i]));
    }

    // nahrazeni v text nodech
    foreach($xpath->query('//text()') as $textNode) {

        $parent = $textNode->parentNode;
        $text = $textNode->wholeText;

        // zpracovat text
        $newNodes = array();
        $lastOffset = 0;
        $char = null;
        $lastChar = null;
        for($i = 0; isset($text[$i]); ++$i) {

            // ziskat znak
            $lastChar = $char;
            $char = $text[$i];

            // preskocit pokud minuly znak nebyl zacatek ci mezera
            if(null !== $lastChar && ' ' !== $lastChar) {
                continue;
            }

            // detekovat slova
            for($ii = 0; isset($wordList[$ii]); ++$ii) {

                // test prvniho znaku slova
                if(0 === strcasecmp($char, $wordList[$ii][0])) {

                    // test ostatnich znaku
                    $offset = 0;
                    for($iii = $i; isset($wordList[$ii][1][$offset]); ++$iii) {
                        if(0 === strcasecmp($wordList[$ii][1][$offset], $text[$iii]) || ord($wordList[$ii][1][$offset]) > 128 && ord($text[$iii]) > 128) {

                            // znak ok
                            ++$offset;
                            if($offset === $wordList[$ii][2]) {

                                /* --- plna detekce slova --- */

                                // preskocit, pokud nasledujici znak neni konec ci mezera
                                ++$iii;
                                if(isset($text[$iii]) && ' ' !== $text[$iii]) {
                                    break;
                                }

                                $wordMode = (!isset($wordModes[$ii]) ? 0 : $wordModes[$ii]);

                                // cast textu pred + slovo
                                if(0 === $wordMode) {
                                    $newNodes[] = new DOMText(
                                        substr($text, $lastOffset, $i - $lastOffset + $wordList[$ii][2])
                                    );
                                } else {

                                    // cast textu pred
                                    $newNodes[] = new DOMText(
                                        substr($text, $lastOffset, $i - $lastOffset - 1)
                                    );

                                    // &nbsp; pred
                                    $newNodes[] = new DOMEntityReference('nbsp');

                                    // + slovo
                                    $newNodes[] = new DOMText(
                                        substr($text, $i, $wordList[$ii][2] + ((1 === $wordMode) ? 1 : 0))
                                    );

                                }

                                // &nbsp; za
                                if(1 !== $wordMode) {
                                    $newNodes[] = new DOMEntityReference('nbsp');
                                }

                                // aktualizovat posledni offset, konec
                                $lastOffset = $i + $wordList[$ii][2] + 1;
                                break;

                            }
                        } else {
                            // neplatny znak
                            break;
                        }
                    }

                }

            }

        }
        $newNodes[] = new DOMText(substr($text, $lastOffset));

        // vlozit nove casti
        for($i = 0; isset($newNodes[$i]); ++$i) {
            $parent->insertBefore($newNodes[$i], $textNode);
        }

        // smazat stary text
        $parent->removeChild(
            $textNode
        );

    }

    // ziskat vysledek
    $out = '';
    foreach($xpath->query('/html/body')->item(0)->childNodes as $item) {
        $out .= $doc->saveXML($item);
    }
    return $out;

}
Jack06
Profil
ShiraNai7:

Jedu do státu česká Republika 155 g/km HDI 1.2 HDI 1.2 kkk g

přidávám před g
Notice: Uninitialized string offset: 63

je to řádek:
                        if(0 === strcasecmp($wordList[$ii][1][$offset], $text[$iii]) || ord($wordList[$ii][1][$offset]) > 128 && ord($text[$iii]) > 128) {

a nějak se mi to nevkládá před ty slova
ShiraNai7
Profil
Jack06:
Testováno na PHP 5.4.0, 5.3.5, 5.2.6..

ini_set('display_errors', '1');
error_reporting(E_ALL | E_STRICT);
$kod = '<p>Jedu do státu česká Republika 155 g/km HDI 1.2 HDI 1.2 kkk g</p>';
echo formatujSlova($kod, array('g'), array(1));

Žádný notice, výsledek:
<p>Jedu do státu česká Republika 155 g/km HDI 1.2 HDI 1.2 kkk&nbsp;g</p>
Jack06
Profil
když si napíšu pouze jedno písmeno, tak se mi tam hodí Uninitialized string offset: 1


// není tam problém s těmi spojkami, co mají jedno písmeno?? když je tam ten řádek, co kontroluje index 1, tedy druhé písmeno
ShiraNai7
Profil
Jack06:
To by mi snad taky házelo notice, ne?
« 1 2 »

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: