Autor Zpráva
juneau
Profil
Zdravím,

mám jednoduchou funkci na nahrazení slov v textu odkazem na související článek. Například: "proteinový,proteinů,protein" => url-nejake-stranky.html. Ta slova si rozdělím čárkou na pole a hledám je v textu a nahrazuji regulérním odkazem.

Jednoduchá operace ale dopadne nechtěně. Při prvním cyklu se nahradí "proteinový", při druhém se nahradí "proteinů", ale při třetím se nahradí všechny výskyty "protein", tedy i v již vytvořených odkazech. Tedy výsledek je třeba

<a href="url"><a href="url">protein</a>ový</a>


Což nechci :) Lámu si hlavu, jak by ten cyklus musel vypadat, abych zjistil, jestli je nahrazované slovo uvnitř odkazu (jiné tagy příliš nevadí) nebo není.
xmark
Profil
A co postupovat při nahrazování od kratších slov k delším?
juneau
Profil
To má zase druhý nechtěný výsledek. Kdybych to pořadí slov otočil, tak to dopadne takto:

<a href="url">protein</a>ový


Kód sice bude funkční a validní, ale není to úplně ono. Ostatní slova se již nenahradí.
xmark
Profil
Myslel jsem, že i rozeznáváš, jestli je to slovo, tzn. že je od okolí odděleno mezerou nebo interpunkcí.
__construct
Profil
juneau:
Ta slova si rozdělím čárkou na pole a hledám je v textu a nahrazuji regulérním odkazem
Čo takto hľadať iba základ slova a ten regulár upraviť na /(slovo(\S+)?)/i
juneau
Profil
xmark: no to je taky možnost, ale neznám dopředu podobu textu. Třeba už to může být:

asdasd asd <a href="nejaky-jiny-web">nejlepší proteinový přípravek</a> asdf asd asd


Ani tady nechci nahrazovat.

__construct: hm, to by můj původní problém asi vyřešilo. Ale ne ten o pár řádků výše.
__construct
Profil
juneau:
Tak to potom pozri tento článok
juneau
Profil
Vyřešil jsem to jinak. Použil jsem preg_replace_callback('~(<a|</a>|protein)~i','nahrazeni',$text);

A v nahrazeni() je logika taková, že když funkce najde <a, nastaví $stav na 0, když najde </a>, nastaví $stav na 1. A najde-li "protein", tak nahrazuje, jen je-li $stav == 1. $stav je 1 jen v případě, že je nalezené slovo "protein" mimo <a a </a>, tedy mimo odkaz.

Je to základ. Teď ještě vyřešit, aby se nenacházelo přímo v tazích (title a spol).

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: