Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Regexp szukanie ciagow wieloliniowych
Forum PHP.pl > Forum > PHP
marcio
Elo pisze system assets-ow i mam problem, gdy szukam kod css/js ktory jest wieloliniowy to moj regexp nie wyszukuje kodu:
  1. preg_match_all('/{@ (javascripts|css) @}\r\n(.*)\r\n{@ end (javascripts|css) @}/', $html, $assets_inline);

To dziala np dla tego:
Kod
{@ css @}
    dsfdsffdsf
{@ end css @}

Ale gdy dam juz kod css:
Kod
{@ css @}
    #login{
        width: 100px;
    }
{@ end css @}

To nie dziala poniewaz jest tam \r\n, jak zrobic tak zeby je tez bralo pod uwage?Probowalem za pomoca \w+, grup itp...itd...ale nic z wyrazen regularnych jestem cienki bolek.

Czy ktos wie jak to zrobic?
amii
Globalny modyfikator s
http://www.php.net/manual/en/reference.pcr...n.modifiers.php
marcio
Jesli zrobie tak jak mowisz nie znajduje mi nic, a dwa rozwala mi strone nie wiem dlaczego ;p
  1. preg_match_all('/{@ (javascripts|css) @}\r\n(.*)\r\n{@ end (javascripts|css) @}/s', $html, $assets_inline);

Jakies inne rozwiazanie?

Nie mozna dodac do (.*) jakies wyrazenia zeby akceptowalo x nowych lini?
abort
Po pierwsze, to nie dodawaj \r\n. Konstrukcja "\r\n(.*)\r\n" użyta przez Ciebie powinna być równoznaczna z "(.*)". Jak zapewne wiesz, "." w tym miejscu oznacza "dowolny znak". W tym także znak nowej linii (niezależnie czy \r, \n czy \r\n). Opcjonalnie możesz popróbować z modyfikatorem "m".
marcio
Kropka z tego co sie orientuje wlasnie nie bierze pod uwage znaku przelamania linii.

Zobacze z modyfikatorem /m ale watpie.
abort
No jednak okazało się, że "m" nie jest konieczny:
  1. $html="{@ css @}
  2. #login{
  3. width: 100px;
  4. }
  5. {@ end css @}";
  6. preg_match_all('/{@ (javascripts|css) @}(.*){@ end (javascripts|css) @}/s', $html, $assets_inline);
  7. echo $assets_inline[2][0];


No chyba że źle zrozumiałem problem.

BTW, to samo możesz uzyskać ze zwykłego preg_replace:
  1. $rep = preg_replace ('/{@ (javascripts|css) @}(.*){@ end (javascripts|css) @}/s', "\\2", $html);


marcio
Nie nie nie dziala to moze wytlumacze lepiej.
Posiadam kod html strony, jednak potrzebuje miec mozliwosc dodawania z osobna do kazdego komponentu/plugin-u/widget-u kod js/css.

W widoku komponentu robie np cos takiego:
Kod
{@ assets type="css" path="sss/ddds/kod.css" @}
{@ assets type="js" path="sss/ddds/kod.js" @}
{@ javascripts @}
    $(document).ready(function() {
        // put all your jQuery goodness in here.
    });
{@ end @}
{@ css @}
    #login{
        width: 100px;
    }
{@ end @}

I chce zeby ta czesc kodu byla wrzucana do HEAD strony...o ile assets mi wyszukuje i podmienia prawidlowo to jesli chodzi o kod css/js w zrodle juz nie dziala.

Poki co kombinuje tak:
  1. class Vf_Assets
  2. {
  3. public function replaceAssets($html)
  4. {
  5. preg_match_all('/{@ assets type="(img|css|js)" path="(.*)" @}/', $html, $assets_external);
  6. preg_match_all('/{@ (javascripts|css) @}(.*){@ end @}/s', $html, $assets_inline);
  7.  
  8. $css = array();
  9. $js = array();
  10. if(sizeof($assets_external[1]) > 0)
  11. {
  12. foreach($assets_external[1] as $key => $type)
  13. {
  14. if($type == 'css')
  15. {
  16. $css[] = '<link rel="stylesheet" type="text/css" href="'.$assets_external[2][$key].'" />';
  17. }
  18. else if($type == 'js')
  19. {
  20. $js[] = '<script type="text/javascript" src="'.$assets_external[2][$key].'"></script>';
  21. }
  22. }
  23. }
  24. if(sizeof($assets_inline[1]) > 0)
  25. {
  26. foreach($assets_inline[1] as $key => $type)
  27. {
  28. if($type == 'css')
  29. {
  30. $css[] = '<script type="text/css">'.$assets_inline[2][$key].'</script>';
  31. }
  32. else if($type == 'javascripts')
  33. {
  34. $js[] = '<script type="text/javascript">'.$assets_inline[2][$key].'</script>';
  35. }
  36. }
  37. }
  38. $cssString = implode("", $css);
  39. $jsString = implode("", $js);
  40. $html = str_replace(array('{@ css @}', '{@ javascripts @}'), array($cssString, $jsString), $html);
  41. $html = preg_replace('/{@ assets type="(img|css|js)" path="(.*)" @}/', '', $html);
  42. $html = preg_replace('/{@ (javascripts|css) @}(.*?){@ end @}/s', '', $html);
  43. }
  44. }

Ale co mi to nie dziala.
Kombinowalem tez z htmlspecilchars/html_entity_decode ale nic bo czasami rozwala strone.
abort
Masz kod
  1. preg_match_all('/{@ (javascripts|css) @}(.*){@ end @}/s', $html, $assets_inline);

w $assest_inline[0] będziesz miał cały dopasowany ciąg, od "{@ css @}" do "{@ end css @}" (z tymi znacznikami włącznie)

w $assets_inline[1] będziesz miał albo "javascript", albo "css" - w zależności od tego, jaki tekst dopasuje
w $assets_inline[2] będziesz miał zawartość tego, co masz między swoimi znacznikami

Musisz użyć $assets_inline[2], tymczasem ja widzę w zaprezentowanym listingu w linii 24 nadal $assets_inline[1]. To świadomie czy przeoczenie?
marcio
No no uzywam $assets_inline[2], za pomoca $assets_inline[1] sprawdzam tylko czy w ogole cos znalazlo, sprawdz dobrze kod, za pomoca $assets_inline[1] sprawdzam jakiego typu jest kod css/javascripts potem wsadzam go w odpowiednie znaczniki.

Problem jest tez taki ze ucina mi np {@ javascripts @}

Czy ktos moglby sprawdzic na swoim serwerze jak to dziala i jaki daje rezultat?
abort
Fakt, zbyt pobieżnie przejrzałem kod. W tej chwili jestem po krótkich testach - i wygląda mi na to, że po zmianie w szóstej linii "(.*)" na "(.*?)" działa lepiej...
marcio
Nie nie dziala to zbytnio, chodzi tu bardziej o to ze tak jakby mu nie pasowal kod html i ucina mi poczatkowe tagi {@ css @}/{@ javascripts @} przez co chyba nie dziala.
abort
Zauważ, że wewnątrz metody wszystko masz teoretycznie OK. Ale coś jest nie tak na końcu, w ostatnich linijkach. Krótkie moje testy pokazały, że coś szwankuje na końcu metody. Pliki z rozszerzeniami php i phps to ten sam plik (hardlink na linuksie).
marcio
Cytat
Ale coś jest nie tak na końcu, w ostatnich linijkach

Dokladnie.

Nie wiem czy problem nie lezy po stronie html choc w to watpie probowalem tez tresc puszczac przez htmlspecialchars i potem na samym koncu robic html_entity_decode czy jakos tak ale w sumie tez nie dzialalo.

EDIT:
  1. class Vf_Assets
  2. {
  3. public function replaceAssets($html)
  4. {
  5. preg_match_all('/{@ assets type="(css|js)" path="(.*)" @}/', $html, $assets_external);
  6. $html = preg_replace('/{@ css_inline @}(.*?){@ end @}/s', '<style type="text/css">\\1 </style>', $html);
  7. $html = preg_replace('/{@ js_inline @}(.*?){@ end @}/s', '<script type="text/javascript">\\1 </script>', $html);
  8. $css = array();
  9. $js = array();
  10.  
  11. if(sizeof($assets_external[1]) > 0)
  12. {
  13. foreach($assets_external[1] as $key => $type)
  14. {
  15. if($type == 'css')
  16. {
  17. $css[] = '<link rel="stylesheet" type="text/css" href="'.$assets_external[2][$key].'" />';
  18. }
  19. else if($type == 'js')
  20. {
  21. $js[] = '<script type="text/javascript" src="'.$assets_external[2][$key].'"></script>';
  22. }
  23. }
  24. }
  25.  
  26. $cssString = implode("", $css);
  27. $jsString = implode("", $js);
  28. $html = str_replace(array('{@ css @}', '{@ javascripts @}'), array($cssString, $jsString), $html);
  29. $html = preg_replace('/{@ assets type="(img|css|js)" path="(.*)" @}/', '', $html);
  30. }
  31. }

Taki kod zalatwia sprawe, preg_match_all ma chyba jakis bug...ogolnie rzecz biorac bede musial sie pobawic z preg_replace_callback zeby wsadzilo mi podmieniony kod w znaczniki <head></head>

Tylko jak?

Nie wazne problem rozwiazany chyba preg_match_all ma jakis bug albo ja cos robilem zle, troche na okolo ale dziala:
  1. class Vf_Assets
  2. {
  3. public function replaceAssets($html)
  4. {
  5. preg_match_all('/{@ assets type="(css|js)" path="(.*)" @}/', $html, $assets_external);
  6. $html = preg_replace('/{@ css_inline @}(.*?){@ end @}/s', '<style type="text/css">\\1</style>', $html);
  7. $html = preg_replace('/{@ js_inline @}(.*?){@ end @}/s', '<script type="text/javascript">\\1</script>', $html);
  8. preg_match_all('/<script type="text\/javascript">(.*?)<\/script>/s', $html, $assets_inline_js);
  9. preg_match_all('/<style type="text\/css">(.*?)<\/style>/s', $html, $assets_inline_css);
  10. $html = preg_replace('/<style type="text\/css">(.*?)<\/style>/s', '', $html);
  11. $html = preg_replace('/<script type="text\/javascript">(.*?)<\/script>/s', '', $html);
  12.  
  13. $css_inline = array();
  14. $js_inline = array();
  15. $css = array();
  16. $js = array();
  17. $inlines = array(
  18. 'css' => $assets_inline_css[1],
  19. 'js' => $assets_inline_js[1]
  20. );
  21.  
  22. if(sizeof($assets_external[1]) > 0)
  23. {
  24. foreach($assets_external[1] as $key => $type)
  25. {
  26. if($type == 'css')
  27. {
  28. $css[] = '<link rel="stylesheet" type="text/css" href="'.$assets_external[2][$key].'" />';
  29. }
  30. else if($type == 'js')
  31. {
  32. $js[] = '<script type="text/javascript" src="'.$assets_external[2][$key].'"></script>';
  33. }
  34. }
  35. }
  36.  
  37. foreach($inlines as $type => $inline)
  38. {
  39. if($type == 'css')
  40. {
  41. foreach($inline as $code)
  42. {
  43. $css_inline[] = "\n<style type=\"text/css\">".$code."</style>\n";
  44. }
  45. }
  46. else if($type == 'js')
  47. {
  48. foreach($inline as $code)
  49. {
  50. $js_inline[] = "\n<script type=\"text/javascript\">".$code."</script>\n";
  51. }
  52. }
  53. }
  54.  
  55. $cssString = implode("", array_merge($css, $css_inline));
  56. $jsString = implode("", array_merge($js, $js_inline));
  57. $html = str_replace(array('{@ css @}', '{@ javascripts @}'), array($cssString, $jsString), $html);
  58. $html = preg_replace('/{@ assets type="(img|css|js)" path="(.*)" @}/', '', $html);
  59. }
  60. }
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.