PHP - Náhrada funkce explode - skript s více oddělovači slov současně
Rozdělení věty na slova; kontrola, oprava a cenzura oddělených slov; znovusestavení věty
23. 7. 2020
Vytvořeno
23.3.2012
Potřeboval jsem se v PHP dostat na jednotlivá slova textového řetězce (rozdělit string na array), ale nestačilo mi větu na slova dělit jen podle mezer, jak se to obvykle s použitím funkce explode dělá, chtěl jsem definovat a použít pole více oddělovačů slov.
Abych izoloval i slova ukončená tečkou, čárkou, závorkou, vykřičníkem, apod.
Protože při postupném použití funkce explode s různými znaky by nebyla oddělena slova, která mají zleva jiný znak než zprava …což je častý případ – za slovem je čárka nebo tečka, ale před slovem je mezera – málokdy je ve větě slovo obklopené tečkami z obou stran, a když už tam je, tak je to stejně typografická chyba. Nemluvě o tom, že bychom pak měli pole polí (i když to se dá vyřešit spojením).
Nic hotového jsem nenašel, tak jsem si ten skript (alternativa k funkci explode) napsal a dávám ho dál…
Protože narozdíl od běžného postupu, kdy se funkcí explode rozdělí řetězec jen tam, kde je mezera
(a kde tedy při pozdějším slepování zpět víme, že mezi jednotlivá slova přijde vždy mezera),
jsem potřeboval uchovat i jednotlivé znaky mezi slovy, abych řetězec nepoškodil,
ukládám si ty oddělovače jako samostatná slova v poli.Pro moje použití to ničemu nevadilo.
Pokud by to vadilo vám, můžete si nalezené oddělovače ukládat do samostatného pole, nebo třeba zahazovat.
Pokud ale potřebujete větu na závěr zase slepit dohromady, komplikovalo by vám uložení oddělovačů v samostatném poli práci – takže je lepší nechat slova i oddělovače takto sypat do jednoho společného pole
– a pokud potřebujete zasahovat jen do slov, ne do oddělovačů, můžete si při procházení pole kontrolovat lichost/sudost (dělitelnost dvěma) pořadí každého prvku v poli.
Sice existují různé alternativy k funkci explode, a to třeba i pro více oddělovačů, ale tento můj skript narozdíl od jiných řešení (alespoň těch, která jsem našel) zachová informaci o původních oddělovačích.
Je tedy určen pro rozebrání věty na slova, kontrolu/opravu/cenzuru jednotlivých slov a opětovné slepení věty se zachováním původních oddělovačů (tečky, čárky, závorky, uvozovky, apod.).
//Rozdělení textového řetězce na prvky pole - náhrada funkce explode - pro více oddělovačů současně //Martin Adámek, www.adamek.cz ///////////////////////////////////// //$oddelovace Pole obsahující jednoznakové oddělovače (Dvouznakové oddělovače jsou definované níže, přímo v kódu) //$co Textový řetězec, který chcete rozsekat na jednotlivá slova // Na závěr se jednotlivě upravená slova slepí zpět zase do této proměnné //$polekontrolovanychslov Pole, do kterého se jednotlivá izolovaná slova uloží ///////////////////////////////////// $oddelovace=array(" ", ".", ",", ";", "-", "?", "!", "_", ":", "(", ")", "/"); $slovo=""; $polekontrolovanychslov=array(); // Rozsekání řetězce (věty) na slova for ($i=0; $i<strlen($co);$i++) { if (substr($co,$i,2)=="\\\"" or substr($co,$i,2)=="\\\\" or substr($co,$i,2)=="\\'") {$polekontrolovanychslov[]=$slovo; $polekontrolovanychslov[]=substr($co,$i,2); $slovo="";$i++;} //odhalení zpětným lomítkem vyescapovaných znaků - zpětného lomítka i obou typů uvozovek elseif (in_array($co[$i], $oddelovace)) {$polekontrolovanychslov[]=$slovo; $polekontrolovanychslov[]=$co[$i]; $slovo="";} else {$slovo.=$co[$i];} } $polekontrolovanychslov[]=$slovo; unset($slovo); /* V tomto místě je celý rozkouskovaný řetězec uložen v poli $polekontrolovanychslov , pro některé aplikace můžete zbytek kódu ignorovat a výše uvedený kód si hodit do funkce. */ // Kontrola, úprava, oprava či jiná cenzura jednotlivých slov foreach ($polekontrolovanychslov as &$prvek) { if ($prvek=="AZeMeNenajdes") $prvek="NaselJsemTe"; /* Tady si s každým izolovaným slovem udělejte, co potřebujete. */ } unset($prvek); // Pospojování opravených slov zpět do jednoho řetězce (zcenzurované věty) $co=implode("",$polekontrolovanychslov); //Protože patřičné oddělovače jsou uloženy jako samostatná slova (prvky pole), můžeme pro znovuspojení řetězce použít běžnou funkci implode //a jako lepidlo (což obvykle bývá mezera, podle které funkce explode řetězec rozdělila) nastavit prázdný řetězec. /* V proměnné $co máme opravenou větu jako jeden textový řetězec. */
Řetězec tak máme zase pohromadě v jedné stringové proměnné, ale hledaná slova jsme upravili, jak jsme potřebovali.
Například jsme je mohli porovnat se seznamem sprostých slov a nahradit je hvězdičkami.
Tento algoritmus tedy můžete použít např. jako základ skriptu pro filtrování vulgárních slov v diskuzích a komentářích, potřebujete-li naprogramovat filtr sprostých slov.
Pokud chcete text jen rozdělit na slova (a nespojovat zpět),
např. pro hledání,
lze to snadněji
Všechny oddělovače lze nejprve nahradit jedním stejným,
a pak provést klasicky explode podle toho jednoho oddělovače, na nějž jsme ty ostatní převedli:
$hledattext = strtr($hledattext,array(' '=>',',';'=>',','.'=>',',':'=>',','!'=>',','?'=>',','('=>',',')'=>',','/'=>',','-'=>',','–'=>',','|'=>',') ); // co vse pouzit jako hranici slov $hledanaslova = explode(',', $hledattext);