Autor | Zpráva | ||
---|---|---|---|
radekt Profil |
#1 · Zasláno: 4. 3. 2012, 09:30:21
Dobrý den, potřebuji regulérními výrazy ze souboru vytáhnout tagy h2 a to, co je mezi nimi. Zvenku to funguje:
<?php $text = file_get_contents('soubor'); if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup)) { foreach ($vystup[0] as $m) echo $m; } ?> Ale já to potřebuji provádět uvnitř souboru a když použiji $text = file_get_contents($_SERVER['PHP_SELF']);, vrátí mi to: [function.file-get-contents]: failed to open stream: No such file or directory in soubor.php on line 4. |
||
Alphard Profil |
#2 · Zasláno: 4. 3. 2012, 09:38:10
Aby script parsoval sám sebe? To vypadá na hodně zvláštní návrh, nechcete raději aplikační a obsahovou vrstvu oddělit?
|
||
DJ Miky Profil |
#3 · Zasláno: 4. 3. 2012, 09:43:12
PHP_SELF začíná lomítkem vzhledem k rootu webu, když to použiješ přímo jako název souboru, pak /soubor.php znamená soubor z rootu disku, který tam samozřejmě není.
Místo toho se dá použít magická konstanta __FILE__ (dvě podtržítka z každé strany), která obsahuje celou absolutní cestu k souboru. Tedy:
file_get_contents(__FILE__) Ovšem je to trochu podivné řešení, jak už píše Alphard. |
||
radekt Profil |
#4 · Zasláno: 4. 3. 2012, 10:20:22
Dobrý den, je to podivné řešení, ale potřebuji to k tomu, abych měl v článku pod hlavním nadpisem nejprve seznam kapitol a pak aby pokračoval vlastní text. Děkuji moc za radu, nyní jsem kód upravil podle rady takto:
<h1>Nadpis</h2> <p>Obsah:</p> <?php $text = file_get_contents(__FILE__); if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup)) { foreach ($vystup[0] as $m) echo $m; } ?> <br> <h2>Kapitola 1</h2> <p>nějaký text</p> <h2>Kapitola 2</h2> <p>nějaký text</p> <h2>Kapitola 3</h2> <p>nějaký text</p> <h2>Kapitola 4</h2> pak si ještě pohraji s kotvami, atd. ale až později. Teď mi to vrací to, co potřebuji, ale za slovo obsah ještě dá (.*?) z regulárního výrazu - jak se toho (.*?) mám ve výpisu zbavit? S regulárními výrazy se teprve seznamuji. Děkuji |
||
radekt Profil |
#5 · Zasláno: 6. 3. 2012, 14:03:10
O něco jsem pokročil:
<h1>Nadpis</h2> <p>Obsah:</p> <?php $text = file_get_contents(__FILE__); // proměnná pro cyklus na výpis obsahu s odkazy $cislo_kapitoly=0; // proměnná pro kotvy ve vlastním dokumentu $kotva = 0; if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup)) { foreach ($vystup[0] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (!StrPos(" ".$m, '(.*?)')) { $cislo_kapitoly++; echo '<a href=#'.$cislo_kapitoly.'>'. strip_tags($m).'</a><br>'; } } } ?> <br> <a id="<?php $kotva++; echo $kotva; ?>"><h2>Kapitola 1</h2></a> <p>nějaký text</p> <a id="<?php $kotva++; echo $kotva; ?>"><h2>Kapitola 2</h2></a> <p>nějaký text</p> <a id="<?php $kotva++; echo $kotva; ?>"><h2>Kapitola 3</h2></a> <p>nějaký text</p> <h2 id ="<?php $kotva++; echo $kotva; ?>">Kapitola 4</h2> <p>nějaký text</p> |
||
Tori Profil |
#6 · Zasláno: 6. 3. 2012, 23:01:37
Asi vám to rozbije funkce strip_tags. Tohle by mělo jít, změny zvýrazněny:
if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup)) { foreach ($vystup[1] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (StrPos($m, '(.*?)') === false) { $cislo_kapitoly++; echo '<a href="#'.$cislo_kapitoly.'">'.$m.'</a><br>'; } } } |
||
radekt Profil |
#7 · Zasláno: 7. 3. 2012, 16:49:18
Dobrý den,
děkuji, perfektní, funguje, jenom se chci zeptat - proč se pole prohledává od prvního a ne od nultého? To mi není jasné. Děkuji |
||
Tori Profil |
#8 · Zasláno: 7. 3. 2012, 17:04:00
radekt:
To není "od prvního prvku" ale "první podvýraz" - tedy ta část v závorkách. Nechte si před cyklem vypsat proměnnou $vystup, ať vidíte, co přesně preg_match_all vrací. A zkuste si taky přidat jako 4. parametr konstantu PREG_SET_ORDER, bude to vracet jinak seskupené pole, jakoby o 90° otočené - někdy se víc hodí tohle. |
||
radekt Profil |
#9 · Zasláno: 7. 3. 2012, 17:26:21
dal jsem tento kód:
preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup); echo $vystup."<br>"; preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup, PREG_SET_ORDER); echo $vystup; Array Array Asi to chápu špatně, ale měl jsem za to, že se vše mezi tagy řadí do nultého až posledního pole - tedy nulté je <h2.*>(.*?)</h2>, první je <h2>Kapitola 1</h2>, druhé <h2>Kapitola 2</h2> atd. Takže jsem se domníval, že jde vypisovat od nultého pole, které se vyloučí podmínkou. Ale když jsem dal v kódu foreach ($vystup[0] as $m) nevrátilo to nic.
|
||
Tori Profil |
#10 · Zasláno: 7. 3. 2012, 18:31:45
Místo echo použijte var_dump, je to dvourozměrné pole.
|
||
radekt Profil |
#11 · Zasláno: 8. 3. 2012, 19:49:18
Výborně, už to chápu, díky za pomoc. Uvažoval jsem i o DOMDocument(), ale toto se mi zdá elegantnější. Zajímalo by mně, jestli ještě někdo řešil takovýto problém a jak. Ještě jednou díky moc.
|
||
radekt Profil |
#12 · Zasláno: 9. 3. 2012, 08:58:31
Kvůli "kosmetice" stránek jsem udělal ještě jednu změnu, a to, aby se obsah negeneroval v případě, že v článku bude jen jedna kapitola:
if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup) && count($vystup[1])>2) { echo 'Obsah:<br>'; foreach ($vystup[1] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (StrPos($m, '(.*?)') === false) { $cislo_kapitoly++; echo '<a href="#'.$cislo_kapitoly.'">'.$m.'</a><br>'; } } } |
||
radekt Profil |
#13 · Zasláno: 9. 3. 2012, 12:02:01
Když jsem celý kód obsah.php:
<?php $text = file_get_contents(__FILE__); // proměnná pro cyklus na výpis obsahu s odkazy $cislo_kapitoly=0; // proměnná pro kotvy ve vlastním dokumentu $kotva = 0; // parsování textu mezi tagy h2 if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup) && count($vystup[1])>2) { echo 'Obsah:<br>'; foreach ($vystup[1] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (StrPos($m, '(.*?)') === false) { $cislo_kapitoly++; echo '<a href="#'.$cislo_kapitoly.'">'.$m.'</a><br>'; } } } |
||
Časová prodleva: 3 dny
|
|||
radekt Profil |
#14 · Zasláno: 12. 3. 2012, 10:50:44
Dobrý den,
všechno funguje výtečně, až na jednu věc. Když je v textu H2 vnořený tag, konkrétně - <h2 id = "10">Vpád <a href="http://antika.avonet.cz/article.php?ID=1601">Dáků</a> do Moesie, povstání v Pontu</h2>, vrátí se mi při generování seznamu kapitol tímto způsobem jen <a href="#10">10. do Moesie, povstání v Pontu</a>. |
||
Keeehi Profil |
if (preg_match_all('~<h2[^>]*>(.*?)</h2>~', $text, $vystup) && count($vystup[1])>2) Nebo použít původní dotaz a pak $vstup[0] a na něj aplikované strip_tags(). Zbavíte se tak toho odkazu (stejně to musíte udělat když to má pak sloužit jako kotva), ale celý text zůstane. |
||
radekt Profil |
#16 · Zasláno: 12. 3. 2012, 14:24:47
tento výraz mi vrátil <a href="#10">10. ">Vpád <a href="http://antika.avonet.cz/article.php?ID=1601">Dáků</a> do Moesie, povstání v Pontu</a>. Začínám se v těch reg. výrazech ztrácet
|
||
Keeehi Profil |
#17 · Zasláno: 12. 3. 2012, 14:57:56
radekt:
Je to nějaké divné. ve vstupním řetězci se 10. nevyskytuje, přesto je ve výstupním obsažen.
if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup) && count($vystup[1])>2) { echo 'Obsah:<br>'; foreach ($vystup[0] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (StrPos($m, '(.*?)') === false) { $cislo_kapitoly++; echo '<a href="#'.$cislo_kapitoly.'">'.strip_tags($m).'</a><br>'; } } } |
||
radekt Profil |
Omlouvám se, ještě jsem u sebe na pc modifikoval kód tak, aby ve výpisu bylo vidět číslo kapitoly a sem jsem to nedal:
if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup) && count($vystup[1])>2) { echo 'Obsah:<br>'; foreach ($vystup[0] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (StrPos($m, '(.*?)') === false) { $cislo_kapitoly++; echo '<a href="#'.$cislo_kapitoly.'">'.$cislo_kapitoly.'. '.$m.'</a><br>'; } } } |
||
radekt Profil |
#19 · Zasláno: 14. 3. 2012, 14:50:59
Tak už vážně nevím. Ještě jsem zkoušel na $vstup[0] aplikovat strip_tags(), jak mi bylo doporučeno, ale tam jsem také pohořel - buď se pro chyby vztekal foreach nebo var_dump.
|
||
radekt Profil |
Další pokus, ale postup jen o slepičí krok. Pokoušel jsem se vyloučit tagy odkazů, ale tento výraz:
preg_match_all("'<h2.*>[^a href.*?>$</a>](.*?)</h2>'", $text, $vystup) <h2 id = "10">Vpád <a href="http://antika.avonet.cz/article.php?ID=1601">Dáků</a> do Moesie, povstání v Pontu</h2> vygeneroval toto: <a href="#10">áků</a> do Moesie, povstání v Pontu</a> Ach jo |
||
radekt Profil |
#21 · Zasláno: 16. 3. 2012, 05:49:00
Rekapitulace:
Tento kód: <h1>Nadpis</h2> <?php $text = file_get_contents(__FILE__); // proměnná pro cyklus na výpis obsahu s odkazy $cislo_kapitoly=0; // proměnná pro kotvy ve vlastním dokumentu $kotva = 0; // parsování textu mezi tagy h2 // provede se, pokud je více než jedna kapitola, tj. výskyt párových tagů h2 více než 2 // počítá se i výraz hodnocený fcí preg_match_all, protože soubor páruje sám sebe if (preg_match_all("'<h2.*>(.*?)</h2>'", $text, $vystup) && count($vystup[1])>2) { echo 'Obsah:<br>'; foreach ($vystup[1] as $m) { // vyloučení řetězce (.*?), protože soubor parsuje sám sebe if (StrPos($m, '(.*?)') === false) { $cislo_kapitoly++; echo '<a href="#'.$cislo_kapitoly.'">'.$cislo_kapitoly.'. '.$m.'</a><br>'; } } } ?> <br> <h2 id ="<?php $kotva++; echo $kotva; ?>">Kapitola 1</h2> <p>tttt</p> <h2 id ="<?php $kotva++; echo $kotva; ?>">Kapitola 2</h2> <p>xxxx</p> <h2 id = "<?php $kotva++; echo $kotva; ?>">Vpád <a href="http://antika.avonet.cz/article.php?ID=1601">Dáků</a> do Moesie, povstání v Pontu</h2> ?> vrátí pro poslední kapitolu toto: <a href="#3">3. do Moesie, povstání v Pontu</a><br><br> z důvodu nenasytnosti reg. výrazu, který se zastaví až u uzavírací závorky > tagu </a>. Změním-li reg. výraz na preg_match_all("'<h2.*?>(.*?)</h2>'", tak se pro změnu zastaví moc brzy - u uzavírací závorky tagu pro php, takže vrátí toto: 3. ">Vpád <a href="http://antika.avonet.cz/article.php?ID=1601">Dáků</a> do Moesie, povstání v Pontu</a> Kód s vystup[0] místo vystup[1] vrátí v obou variantách toto: <h2 id = "<?php $kotva++; echo $kotva; ?>">Vpád <a href="http://antika.avonet.cz/article.php?ID=1601">Dáků</a> do Moesie, povstání v Pontu</h2> Když se pokouším vyhodit tagy: echo '<a href="#'.$cislo_kapitoly.'">'.$cislo_kapitoly.'. '.strip_tags($m).'</a><br>'; vyhodí to text úplně a vrátí: Obsah:<br><a href="#1">1. </a><br><a href="#2">2. </a><br><a href="#3">3. </a><br><br> Jak použít strip_tags na vystup[0], na to jsem nepřišel. Už jsem vyzkoušel všechno možné a rezignuji - vyházím prostě vnořené tagy <a> a bude to fungovat |
||
Časová prodleva: 10 dní
|
|||
radekt Profil |
Takže jsem to nakonec vyřešil takto (a dosti čuňácky):
$cislo_kapitoly++; // vyloučení tagu odkazu - začátek $m = preg_replace('"<a href.*?>"',"",$m); // vyloučení tagu odkazu - konec $m = preg_replace('"</a>"',"",$m); // <h2.*> je moc nenasytný a zastaví se až za odkazem - zmizí text mezi tagy odkazu // to samé s otazníkem se naopak zastaví moc brzy - u uzavírací značky php, takže je nutno vyloučit řetězec "> $m = preg_replace('"\">"',"",$m); echo '<a href="#'.$cislo_kapitoly.'">'.$cislo_kapitoly.'. '.$m.'</a><br>'; |
||
radekt Profil |
#23 · Zasláno: 26. 3. 2012, 14:29:00
Druhá varianta je použití strip_tags:
$m = strip_tags($m, '<h2>'); $m = preg_replace('"\">"',"",$m); echo '<a href="#'.$cislo_kapitoly.'">'.$cislo_kapitoly.'. '.$m.'</a><br>'; |
||
Časová prodleva: 12 let
|
0