Autor Zpráva
peteo
Profil
Dobrý deň, večer, ráno,

pre tvorbu rss.xml potrebujem z vkladaného textu do rss do <description> odstrániť entity tvaru &nbsp;, teda všetky &cokolvek; (rss.xml to nechce brať).
existuje možnosť vytvorenia poľa, kde tieto entity budú obsiahnuté bez toho, aby som ich všetky musel vypisovať?, niečo ako napr.:

$stare=array("&".nejaky_zastupny_znak.";");
$nove=str_replace($stare,"",$text);

Potreboval by som vedieť, či to ide a čo má byť to nejaky_zastupny_znak.

Ďakujem.

PS: nevadí mi, že všetky entity (nie je ich až tak veľa, jedná s väčšinou a grécke znaky alfa, beta, ...) budú nahradené "", " ", "?".
juriad
Profil
Udělej to regulárním nahrazením: preg_replace a chceš nahrazovat /&[^;]*;/

Snad se naučíš preg, jak píšeš vedle.
preg_replace("/&[^;]*;/", "", $text);



Ten regulární výraz má význam: úsek (to značí ty lomítka), který se skládá z: ampersand, cokoli co není středník ([] značí výčet znaků, ^ negaci výčtu) opakuj kolikrát to půjde (hvězdička), středník
peteo
Profil
juriad:

takže stačí
$text=preg_replace("/& * /;", "", $text);

z tých modifikátorov som trocha jeleň.
alebo tá hviezdička musí byť v zátvorke?

$text=preg_replace("/& (*) /;", "", $text);
juriad
Profil
regulární výraz musí začínat a končit lomítkem (určitě narazíš i na jiné znaky, ale historicky to tak bylo, teoreticky můžeš použít cokoli - ale stejné na začátku i na konci)
za lomítkem bude ampersand - první znak, který chceš aby se shodoval při hledání
následuje konstrukce [^&]* - cokoli co není středník (*1)
před koncovým lomítkem bude středník - poslední znak, který chceš najít

určitě tam nepatří mezery - mezera má v regulárním výrazu význam mezera v textu
sťredník je středník, je to obyčejný znak, není to ukončovač příkazu, jako v PHP
hvězdička říká, že předchozí část se může opakovat kolikrát chce, lze tu část i vypustit
závorka má význam skupina: tuto část považuj za jeden celek

(*1) pokud bys řekl jen cokoli zapáno jako: .* - tečka znamená jakýkoli jeden znak, hvědička ho iteruje - tedy posloupnost i délky nula jakýcholi znaků, jenže v případě textu:
"recke pismeno &alpha;, dalsi recke pismeno &beta;, a to je vse" by bylo výsledkem "recke pismeno , a to je vse"
další možné řešení problému se sežráním velkého kusu je použít místo hvězdičky (* - sežer co jen půjde) jejího nežravého bratříčka (*? - sežer jen co musíš) a v takovém případě můžeš použít jen tečku místo [^;].

dva výrazy které dělají to co chceš jsou:
/&[^;]*;/ - tento bude fungovat úplně ve všech variantách regulárních výrazů
/&.*?;/ - tento výraz bude fungovat ve všech funkcích, které podporují Perlové REGulární výrazy
peteo
Profil
juriad:


díky:

čiste len pre kontrolu:
/ pred znakom je prvý znak, / za znakom je posledný znak kontrolovaného výrazu
[^] mi vymedzuje, čo nemá spracovať (ak obsahuje znak v [^] (napr. [^;], teda ;), tak výraz ignoruj a nespracovávaj ho

nakoľko je logické, že entita by nemala obsahovať ďalší stredník, vyhovujúci zápis je

$text=preg_replace("/&.*?;/", "", $text);

dobre. Vďaka, takto lopatisticky to je fajn.

Často som sa stretol i s lomítkom \.
Môžem poprosiť ešte o vysvetlenie jeho použitia?
juriad
Profil
v Perlových regulárních výrazech má téměř každý znak speciální význam, už jsi takových znaků potak několik:
* lomítko - začíná nebo ukončuje regulární výraz, pokud by se mělo objevit někde uvnitř výrazu, musíš ho escapovat - vrátit mu jeho normální význam - znak lomítko:
"/[0-9]\/[1-9]/" - regulární výraz, kterému odpovídají všechny jednociferné zlomky, například "3/6"

* hvězdička - znamená předchozí část iteruj kolikrát chceš, ale pokud ji chceš použít jako znak, musíš ho escapovat - "/[1-9][0-9]*\*[1-9][0-9]*/" - regulární výraz, kterému vyhoví všechny součiny čísel: "256*5"

* plus - pokud chceš aby se něco opakovalo alespoň jednou, x+ je zkratka xx*, součet dvou čísel volitelně začínajících nulou: "/[0-9]+\+[0-9]+/" - vyhoví například "0+020"

* otazník - předchozí část se může nebo nemusí objevit, výrazu "/[0-9][0-9][0-9] ?[0-9][0-9]" odpovídají PSČ: "123 45", ale i "12345" (před otazníkem je mezera)

* tečka - zastupuje jakýkoli jeden znak - desetinné číslo tedy musíš zapsat jako "/[0-9]+\.[0-9]*/" - vyhoví "123.34", ale i "0."

* hromada dalších znaků, po paměti: svislítko - alternativa, hranaté závorky - výčet, složené závorky - omezení počtu iterací, stříška - začátek textu, dolar - konec textu, kulaté závorky - skupina

pro nalezení jakéhokoli z těchto znaků musíš před něj napsat zpětné lomítko, protože jinak by byl chápán jako "speciálně"

naopak u písmen a číslic nikdy nepíšeš zpětné lomítko, pokud náhodnou necheš od nich něco speciálního:
* d = znak d, ale \d = jakákoli číslice, předchozí výraz pro PSČ by šel přepsat jako: "/\d{3} ?\d{2}/" = "/\d\d\d ?\d\d/"


schrnutí (*1):
znak\escapovaný     |   ANO     |    NE     |
---------------------------------------------
písmeno, číslo      | speciální | normální  |
něco jiného         | normání   | záleží    |
záleží znamená, že pokud existuje speciální význam, tak ho nabývá, pokud neexistuje, chová se normálně: "/posloupnost plusů: \+* a mínusů: -*/" vyhoví: "posloupnost plusů: +++++ a mínusů: ------"

(*1) platí pro Perlové regulární výrazy, u rozšířených - extended - ereg, a základních - basic - breg je to úplně divoké
peteo
Profil
excelentné, konečne pochopiteľné.

ešte strieška:

pri [^a-z] ignoruje znaky pri vyhľadávaní (zamieňaní)
pri ^[a-z] zamieňa práve tieto znaky?

a ak som dobre pochopil, medzera v zápise je chápaná ako medzera, teda dávať si na to bacha. well.
dobre, a ak chcem definovať skupinu znakov povedzme znaky väčšie ako chr (386) (grécke znaky) alebo iné (napr azbuku), to ako zapíšem - to chr (xxx)?

Ďakujem
juriad
Profil
stříška: chová se pěti různými způsoby :)
1/ Pokud je volně v regulárním výrazu a je escapovaná: výrazu "/6\^2/" vyhoví text "6^2"
2/ Pokud je na začátku regulárního výrazu (za lomítkem), tak znamená: začátek řádku, textu; regulárnímu výrazu: "/^6\^2/" vyhovuje v textu "6^2, 6^2, 66^2" pouze ta první část, stříška říká, že text jím musí začínat, obdobně se chová i dolar ($), ale ten funguje na konci textu
2.1/ Volně v textu bez escapování, ne na pvní pozici - toto nemá smysl, nemůžeš mít text, tak aby před jeho začátkem bylo ještě něco napsaného
3/ Pokud je uvnitř hranatých závorek ne na první pozici, tak se je součástí výčtu: výrazu "/[0-9^]*/" vyhovuje libovolné mocnění: "2^3", "^2^^3"
4/ Pokud je unitř hranatých závorek na první pozici, tak invertuje výčet: výrazu "/[^0-9]*/" vyhovuje každý text, který neobsahuje znaky "0123456789^"
5/ Pokud je escapovaný uvnitř hranatých závorek, tak se chová stejně jako v případě 3 a nejde o inverzi, příklad: "/[\^0-9]/" je identické případu 3

"/^\^[^^]/" - text, který začíná (první stříška za lomítkem) stříškou (escapovaná stříška) a po ní následuje jeden znak, který není stříška (invertovaný výčet obsahující stříšku)

mezera je vždy mezera, nemá žádný speciální význam

skupinou je myšlena skupina po sobě jdoucích znaků, například "/(\+420)?\d{9}/" - vyhoví jakékoli telefoní číslo, přičemž úvodní +420 je nepovinné
ty asi chceš třídu znaků definovanou rozsahem - čárka uvnitř hranatých závorek: "[a-z]" jsou malá písmena anglické abecedy
"[\N{U+0400}-\N{U+04FF}]" by snad mohlo fungovat, ale netuším, jak je na tom implementace v php
peteo
Profil
super.
po lopate a jasne.
dúfam, že to takto bude aj v pripravovanom manuáli.

Ďakujem.

I keď miestami mám z toho ešte chaos, ale vyznám sa.
Odkladám ako ťahák, kým sa mi to dostane do krvi.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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

0