Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Parsowanie tablicy z preg_replace?
Forum PHP.pl > Forum > PHP
LamaMASTER
Zrobiłem sobie taką funkcję:
  1. <?php
  2.  
  3. function [...]
  4. {
  5. $szukaj = array (
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. "echo '\\1';"
  10. );
  11. return preg_replace($szukaj, $zamien, [...]);
  12. }
  13.  
  14. ?>

Specialnie dodałem po jednej wartości do tablic. Działa on w ten sposób, że przy zastosowaniu funkcji zamienia mi np. [cokolwiek] na "echo 'cokolwiek'". Problem w tym, że preg_replace nie parsuje php i dlatego moje "echo 'cokolwiek'" pozostaje widoczne w kodzie (nawet jeżeli dodam <? i ?> to też je widać). Pomyślałem więc o eval. Zrobiłem wpierw tak:
  1. <?php
  2.  
  3. function [...]
  4. {
  5. $szukaj = array (
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. "echo '\\1';"
  10. );
  11. $wynik = preg_replace($szukaj, $zamien, [...]);
  12. return eval($wynik);
  13. }
  14.  
  15. ?>

Ale wtedy miałem parse error gdy kod zawierał np. normalny tekst czy tagi html. Pomyślałem więc o evaluowaniu samej tablicy zamień:
  1. <?php
  2.  
  3. return preg_replace($szukaj, eval($zamien), [...]);
  4.  
  5. ?>

Ale też miałem byki, bo eval nie parsuje tablic. Zdecydowałem się na najwolniejszą z możliwości:
  1. <?php
  2.  
  3. function [...]
  4. {
  5. $szukaj = array (
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. eval("echo '\\1';")
  10. );
  11. return preg_replace($szukaj, $zamien, [...]);
  12. }
  13.  
  14. ?>

Teraz tekst jest parsowany, ale mam błędy w wynikach, ponieważ tekst zostaje parsowany ZANIM preg_replace go zamieni, czyli w rezultacie widzę "/1" zamiast "cokolwiek".
Może zadanie trudne - ale jak sobie poradzić z tym, żeby preg_replace najpierw zamieniało, a potem TYLKO zamieniony tekst został parsowany?
phobos
Moze takie cos pomorze

  1. <?php
  2.  
  3. function lol($text)
  4. {
  5. $szukaj = array (
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. "'\\1'"
  10. );
  11. return print(preg_replace($szukaj, $zamien, $text));
  12. }
  13.  
  14. lol("[cokolwiek]");
  15. ?>
LamaMASTER
Z tym już kombinowałem, tzn. samo danie \\1. Oczywiście tekst wyświetla, ale np. chciałbym dodać "echo $zmienna['\\1'];" do tablicy i co wtedy? Z Twoim sposobem także wyświetla mi to jako tekst, a ja chcę, żeby najpierw zamieniło się na "echo $zmienna['cokolwiek'];" a potem zostało przeparsowane i wyświetliło tą zmienną (tutaj wystarczy eval), ale jak zastosować eval po przeparsowaniu - sposobu jeszcze nie znalazłem. Jednak dzięki za odpowiedź i czekam na dalsze sugestie winksmiley.jpg
phobos
tak questionmark.gif

  1. <?php
  2.  
  3. function lol($text)
  4. {
  5. $szukaj = array (
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. "echo '\\1';"
  10. );
  11. return eval(preg_replace($szukaj, $zamien, $text));
  12. }
  13. lol("[cokolwiek]");
  14. ?>


albo tak

  1. <?php
  2.  
  3. function lol($text)
  4. {
  5. $szukaj = array (
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. "echo '\\1';"
  10. );
  11. return preg_replace($szukaj, $zamien, $text);
  12. }
  13. eval(lol("[cokolwiek]"));
  14. ?>
LamaMASTER
Też próbowałem, ale przypuśćmy, że robię sobie tak:
lol("<div align="center">[cokolwiek]</div>");
i teraz po przeparsowaniu mam błąd w divie, bo jest zapisany bez echo. Rozumiesz o co chodzi? W tym właśnie jest problem. Kombinowałem różnie z tym i jedyne co mi przychodzi do głowy, to przeparsowanie jedynie zamienionego tekstu, nie całości
Wave
może preg_replace_callback ? albo modyfikator "e" ?
phobos
ej czyli ty chcesz cos takiego
w tablicy chcesz miec "echo <div aling='center'>cokolwiek</div>"
ale zeby na stronce to sie wyswietlalo samo cokolwiek (tyle ze na srodku) questionmark.gif
LamaMASTER
Wave - posprawdzam.
Phobos - nie sugeruj się przykładem jaki podaję, on nie ma związku, wiem, że to można zrobić prościej, ale chcę np. mieć tak:
funkcja('<div align="center">[cokolwiek]</div>'); niech mi zamieni na <div align="center">cokolwiek</div>, ale pod warunkiem, że cokolwiek będzie w echo, tzn. echo 'cokolwiek';
Może być jeszcze inna funkcja zamiany zamiast preg_replace. Ważne, żeby działało. Chodzi głównie o to, żeby z większego tekstu pozamieniać kilka takich [coś] tak jak pisałem powyżej.

edit

callback pokazuje mi błąd:
[...] preg_replace_callback() requires argument 2, 'Array', to be a valid callback [...]
A według manuala powinno parsować, tylko kurcze chyba tablic nie obsługuje sad.gif

edit

Myślałem jeszcze nad array_merge:
  1. <?php
  2.  
  3. $zamien = array (
  4. '[(.*?)]' => 'echo "\\1";'
  5. );
  6.  
  7. $wynik = array_merge($zamien);
  8. return $wynik;
  9.  
  10. ?>

Musiałbym to jak co przerobić, tekst parsuje, ale w wyniku mam tylko napis "Array" - dlaczego?
phobos
aha czyli ty chcesz aby byla taka funkcja ktora przeszuka caly tekst i pozamienia wszystkie " [costam] " na " costam ", czyli prosciej mowiac pousuwa nawiasy??

bo jak tak to sprubuj cos takiego ereg_replace("szukany slowo","slowo zamienne","jakis tekst")

czyli np
  1. <?php
  2.  
  3.  
  4. $tekst="<div align='center'>[costam]</div>";
  5. $tekst=ereg_replace("[ [ ]", "",$tekst);
  6. $tekst=ereg_replace("[ ] ]","",$tekst);
  7.  
  8. ?>
LamaMASTER
Nieeee. Pousuwać nawiasy to ja mogę za pomocą str_replace
$wynik = str_replace("[", "", $wynik);
Ale nie w tym rzecz. Przecież to by był banał. Ja bym chciał, żeby mi wszystkie [cokolwiek] zamieniło na dosłownie echo 'cokolwiek'; i przeparsowało php. Np. potem chciałbym, żeby zamieniało [cokolwiek] na zmienną $cokolwiek i co wtedy? Usunę nawias i wyświetli mi cokolwiek, to nie ma sensu. Musi zamieniać na echo 'cokolwiek', inaczej nie pisałbym tego tematu
phobos
ok man zrobilem cos takiego funckja ktora w tekscie "<div align=\"center\">[cokolwiek]</div>" zmienia [cokolwiek] na $cokolwiek
a potem mozesz sobie za ta zmienan podstawic co chcesz i ona sie wyswietli

  1. <?php
  2.  
  3. function lol($text)
  4. {
  5. $text=preg_replace('#\[(.*?)\]#si','\$\\1',$text);
  6. $text=addslashes($text);
  7. $text2="echo \"";
  8. $text2 .=$text;
  9. $text2 .="\";";
  10. return $text2;
  11. }
  12.  
  13. $text="<div align=\"center\">[cokolwiek]</div>";
  14. $cokolwiek="lol";
  15. echo eval(lol($text));
  16.  
  17. ?>


jak to nie to to masakra, napisz w punktach co chcesz zrobic :-)
LamaMASTER
Wielkie dzięki, to jest już postęp. Zastosowałem to w swojej funkcji, bo tak naprawdę to mam te <div align="center">[cokolwiek]</div> w innym pliku. Np. jest to zamiana.html. To teraz funkcja wygląda tak:
  1. <?
  2. function lol($text)
  3. {
  4. $szukaj = array (
  5. "#\[(.*?)\]#si"
  6.  
  7. );
  8. $zamien = array (
  9. '\$\\1;'
  10. );
  11.  
  12. $text = preg_replace($szukaj, $zamien, $text);
  13. $text = addslashes($wynik);
  14. $display = "echo \"";
  15. $display .= $text;
  16. $display .= "\";";
  17. return eval($display);
  18. }
  19. ?>

Dalej mam np. index.php i w nim:
  1. <?php
  2.  
  3. $cokolwiek = 'to działa';
  4. $string = file_get_contents('zamiana.html');
  5. $string = lol($string);
  6. echo $string;
  7.  
  8. ?>

Według mojego rozumowania - jest funkcja zamieniająca wszystkie [cokolwiek] na $cokolwiek, potem do zmiennej $string jest pobierana zawartość pliku zamiana.html, gdzie jest "<div align="center">[cokolwiek]</div>", na koniec zawartość ta jest zamieniana przez funkcję, parsowana i wyświetlana. W efekcie nie mam już naszczęście parse errorów itp., ale zamiast "to działa" widzę tylko średnik ; W czym teraz problem? biggrin.gif
phobos
po pierwsze primo mussz zamienic
  1. <?php
  2.  
  3. $text = addslashes($wynik);
  4. ?>

na to
  1. <?php
  2. $text = addslashes($text);
  3. ?>

po drugie primo stosujesz eval w funkcji
  1. <?php
  2.  
  3. return eval($display);
  4. ?>

ale w tej funckji nie ma zdefiniowanej zmiennej $cokolwiek wiec takjakby $cokolwiek="" i temu nic ci sie nie wyswietla albo wywal eval na sam koniec tak jak ja zrobilem albo wczytuj $cokolwiek do funckji
po trzecie primo
  1. <?php
  2.  
  3. $zamien = array (
  4. '\$\\1;'
  5. );
  6. ?>

nie dawaj tam srednika na koncu ja juz go uzylem tutaj
  1. <?php
  2. $display = "echo \"";
  3. $display .= $text;
  4. $display .= "\";";
  5. ?>
LamaMASTER
Cytat
po pierwsze primo mussz zamienic
nie dawaj tam srednika na koncu ja juz go uzylem tutaj

Nieuwaga smile.gif

Wielkie dzięki, teraz to działa jak trzeba winksmiley.jpg Spróbuję sobie to teraz urozmaicić jeszcze i jak coś to się zgłoszę ponownie biggrin.gif

edit

Wszystko działa fajnie, jednak co jeśli chciałbym mieć np. zamiast [cokolwiek] zmienną, a zamiast [plik:cokolwiek] include pliku? Taki mini system szablonów. Aktualnie mam tak:
  1. <?
  2. function lol($text)
  3. {
  4. $szukaj = array (
  5. "#\[(.*?)\]#si"
  6. );
  7. $zamien = array (
  8. '\$\\1'
  9. );
  10.  
  11. $wynik = preg_replace($szukaj, $zamien, $text);
  12. $wynik = addslashes($wynik);
  13. $display = "echo \"";
  14. $display .= $wynik;
  15. $display .= "\";";
  16. return $display;
  17. }
  18.  
  19.  
  20. $cokolwiek = 'cokolwiek coś';
  21. $cokolwiek2 = 'coś tam bedzie';
  22. $cokolwiek3 = file_get_contents('text.txt');
  23.  
  24. $string = file_get_contents('plik.html');
  25. $string = eval(replace($string));
  26. echo $string;
  27. ?>

I chciałbym teraz zrobić tak:
  1. <?
  2. $szukaj = array (
  3. "#\[(.*?)\]#si",
  4. "#\[plik(.*?)\]#si"
  5. );
  6. $zamien = array (
  7. '\$\\1',
  8. '\$\\1'
  9. );
  10. ?>

No i właśnie nie wiem jak dodać drugą pozycje w tablicy. Include dać nie mogę, bo wszystko poprzedzane jest echo. Próbowałem usunąć poprzedzające echo i wpisywać je w tablicy, ale mam znowu mój stary parse error. Byłbym wdzięczny za rozwiązanie problemu i najchętniej jeżeli się da to chciałbym, żebym mógł bawić się w tablicy tak:
  1. <?
  2. $szukaj = array (
  3. "#\[(.*?)\]#si",
  4. "#\[plik(.*?)\]#si"
  5. );
  6. $zamien = array (
  7. 'echo \$\\1;',
  8. 'include('\$\\1');'
  9. );
  10. ?>

bo te definiowanie zmiennych to trochę taka sprawa, że wolniej generuje stronę jeżeli tych zmiennych jest dużo. W dodatku include do zmiennej nie da się dodać.
Z góry dzięki!
phobos
sluchaj ale jest jeden szczegół
popatrz dla takiego czegos "[plik:cokolwiek]"
wyrazenie "#\[(.*?)\]#si",jak i "#\[plik(.*?)\]#si" zwruca true
ja proponuje zebys zamienil je miejscami czyli daj w tablicy tak
  1. <?php
  2. $szukaj = array (
  3.  "#\[plik(.*?)\]#si",
  4. "#\[(.*?)\]#si"
  5. );
  6. ?>


i teraz takie cos
  1. <?php
  2.  
  3. foreach($szukaj as $index => $value)
  4.  if(preg_match($value,$text)==1) break; 
  5.  
  6. ?>

pozniej ten preg_replace
i teraz w zalerznosci od $index mozesz sobie dac echo albo include
LamaMASTER
Kurcze Ty to masz łeb biggrin.gif Teraz się trochę pogubiłem, więc to ma być tak?:
  1. <?
  2. function lol($text)
  3. {
  4. $szukaj = array (
  5. "#\[plik(.*?)\]#si",
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9. 'echo \$\\1;',
  10. 'include('\\1');'
  11. );
  12.  
  13. foreach($szukaj as $index => $value)
  14.  if(preg_match($value,$text)==1) break; 
  15. $wynik = preg_replace($szukaj, $zamien, $text);
  16. $wynik = addslashes($wynik);
  17. $display .= $wynik;
  18. return $display;
  19. }
  20.  
  21.  
  22. $cokolwiek = 'cokolwiek coś';
  23. $cokolwiek2 = 'coś tam bedzie';
  24. $cokolwiek3 = file_get_contents('text.txt');
  25.  
  26. $string = file_get_contents('plik.html');
  27. $string = eval(replace($string));
  28. echo $string;
  29. ?>


edit

Sprawdziłem. W rezultacie mam mój stary błąd:
Cytat
Parse error: parse error, unexpected '<' in [...] : eval()'d code on line 1
phobos
mam takie cos tylko tam se pozniej pozamieniaj na ten plik ktory ty chcesz wczytac
  1. <?
  2. function replace($text)
  3. {
  4. $szukaj = array (
  5. "#\[plik:(.*?)\]#si",
  6. "#\[(.*?)\]#si"
  7. );
  8. $zamien = array (
  9.  "\");include(\$\\1);print (\"",
  10.  '\$\\1'  
  11. );
  12.  
  13. foreach($szukaj as $index => $value)
  14.  if(preg_match($value,$text)==1) break; 
  15.  $wynik = addslashes($wynik);
  16. $wynik = preg_replace($szukaj[$index], $zamien[$index], $text);
  17.  
  18.  
  19.  $display= "print (\"";
  20.  $display .= $wynik;
  21.  $display .="\");";
  22. return $display;
  23. }
  24.  
  25. $string="<div align='center'>[cokolwiek]</div>";
  26. $cokolwiek = 'cos.txt';
  27.  
  28. $string = eval(replace($string));
  29. echo $string;
  30. ?>

i teraz jak bedzie [cokolwiek] to wypisze zmienna $cokolwiek a jak bedzie [plik:cokolwiek] to zaincluduje plik ktory jest podany w zmiennej $cokolwiek
LamaMASTER
Ale kombinujesz na około, jak było print tak jest hehe, tylko te średniki. Nie idzie tego zrobić tak jak chciałem, żeby w tablicy podawać prosto funkcje, bez takich kombinacji ze średnikami itp.?
W dodatku nie parsuje za dobrze i po zamianie widzę:
"); include(\'cokolwiek.html'); print ("
phobos
tzn chodzi o to ze jak masz <div....> to pozniej ja dasz samo include to on bedzie probowal zrobic takie cos
include(<div align='center'>costam.html</div>)";
a takiego pliku napewni nie masz a jak zastosowalem print i pozniej ta"zabawe srednikami" to div bedzie dziaall i inculde tez bo masz takie cos

print(<div align='center');inculde('costam.html');print(</div>)";

mozesz sobie usunac ten print i te sredniki ale bedziesz mial parse error jak bedziesz dawal do funkcji <div align='center'>[plik:costam]</div>
chyba ze jeszcze przed dostarczeniem tektu do funkcji podzielisz go na takie czesci
1-- <div align='center'>
2-- [plik:costam]
3--</div>
pozniej do funcki dasz tylko te 2 czesc a potem na nowo skleisz calosc
LamaMASTER
O to zleksza kiepsko. Czemu jest ten parse error? A nawet jeśli bym miał print(<div align='center');inculde('costam.html');print(</div>)"; to i tak include powino zadzialać, bo w końcu jest po średniku. Dzielenie pliku na części też nie ma sensu, bo jak znaczników będzie więcej i jak tagów też będzie więcej? Najlepszy sposób byłby taki, że po prostu parsowana byłaby jedynie zawartość zamienionego znacznika po zamianie, ale z tego co widzę nie ma takiej możliwości. Usunąć print też nie ma możliwości żeby nie było parse errora? Kurcze no tak nie może być... jest jakiś inny replacer prócz preg_replace? Albo mógłbym skorzystać z samego zamieniania na zmienne, gdyby nie to, że jeśli zrobię np. $zmienna = include('plik'); to nie zadziała. Fatalnie. Masz jakieś propozycje żeby te dwa znaczniki działały i się nie gryzło nic?
phobos
w php nie mozesz uzywac sobie tagów html bo wyskakuje error tak jest zbudowane
( napisz sobie cos takiego
  1. <?php
  2. <
  3. ?>
-- ten samo error co wysakuje tobie)
mozesz uzywac html tylko w funckach echo albo print dlatego jak usniesz print z tego co ci dalem to wyskakuje blad
narazie nie mam lepszego pomyslu ten co dalem na dzisiaj jest najlepszy moze wpadniesz kiedys na inny to pisz na forum pomoge jak cos
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.