Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> wyrażenie regularne
nospor
post
Post #1





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Mam taki ciąg
Kod
START bla bla bla END inneblabla inneblabla

Chcę zamienić wszystko między START a END na coś innego, włącznie ze START i END.
No to piszemy proste wyrażenie:
  1. $text = 'START bla bla bla END inneblabla inneblabla';
  2. $text2 = preg_replace('/^START\s.*?\sEND/','#zamienione#',$text);
  3. echo $text2;

W rezultacie otrzymamy:
Kod
#zamienione# inneblabla inneblabla

Proste.
Sprawa się komplikuje, gdy pomiędzy START i END włożym podSTART i pod END
Kod
START bla bla bla START blablaW END bla3 END inneblabla inneblabla

W wyniku naszego wyrażenia otrzymamy
Kod
#zamienione# bla3 END inneblabla inneblabla

A powinniśmy otrzymać to samo co w pierwszym przypadku.
No to powiecie: zamien .*? na .* i po sprawie. No nie do końca, bo jest jeszcze jeden przypadek, ze START i END pojawi nam się też rownożędnie do pierwszego, czyli np:
Kod
START bla bla bla START blablaW END bla3 END inneblabla START ccc xxx END inneblabla

Zrobie .* da nam
Kod
#zamienione# inneblabla

a mi chodzi, by uzyskac
Kod
#zamienione# inneblabla START ccc xxx END inneblabla


Podsumowując:
ma być zamienione tylko pierwsze główne START END, nawet jeśli ma w sobie inne START END, ale nie można już ruszych późniejszych START END
Idzie to zrobić wyrażeniem regularnym?
Go to the top of the page
+Quote Post
kreciko
post
Post #2





Grupa: Zarejestrowani
Postów: 99
Pomógł: 7
Dołączył: 17.02.2010

Ostrzeżenie: (0%)
-----


Musisz w środku tego wyrażenia dodać bardzo podobne, które może wystąpić 0 lub więcej razy. Nie wiem czy dobrze zapisałem:

Kod
^START\s(START\s.*?\sEND)*\sEND


Ten post edytował kreciko 28.09.2010, 08:19:24
Go to the top of the page
+Quote Post
nospor
post
Post #3





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Juz myslalem ze bedzie dobrze ale nie
  1. $text = 'START bla bla bla START blablaW END bla3 END inneblabla START ccc xxx END inneblabla';
  2. $text2 = preg_replace('/^START\s.*?(START\s.*?\sEND)*.*?\sEND/','#zamienione#',$text);
  3. echo $text2;

Nadal zwraca mi
Kod
#zamienione# bla3 END inneblabla START ccc xxx END inneblabla

Gdy zamienie (START\s.*?\sEND)* na (START\s.*?\sEND)+ to zwraca juz dobrze, ale tylko dla przypadku, gdy te wewnetrzne START END istnieje. Gdy nie będzie istnialo, znowu się wykrzaczy
Go to the top of the page
+Quote Post
kreciko
post
Post #4





Grupa: Zarejestrowani
Postów: 99
Pomógł: 7
Dołączył: 17.02.2010

Ostrzeżenie: (0%)
-----


  1. $text2 = preg_replace('/^START.*(START.*END)*.*END/','#zamienione#',$text);


Ten post edytował kreciko 28.09.2010, 09:07:25
Go to the top of the page
+Quote Post
nospor
post
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




kreciko ale wowczas łyknie też tego ostatniego END a pisałem ze tego nie chce (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
wookieb
post
Post #6





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




preg_replace_callback i trochę rekurencyjnych wywołań.
Nie możesz się posługiwać operatorami kontrolującymi chciwość np (?)
Go to the top of the page
+Quote Post
nospor
post
Post #7





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Nie możesz się posługiwać operatorami kontrolującymi chciwość np (?)
To pytanie czy stwierdzenie?
Go to the top of the page
+Quote Post
wookieb
post
Post #8





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




"?" to operator leniwego wybierania znaków
Go to the top of the page
+Quote Post
nospor
post
Post #9





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




To ja wiem, pytam sie ciebie czy twoj ostatni post to pytanie czy stwierdzenie (IMG:style_emoticons/default/smile.gif)
Bo jak przejrzysz kody to zauwazysz, ze uzywam leniwego wybierania znaków wiec nie rozumiem sensu twojego zdania
Cytat
Nie możesz się posługiwać operatorami kontrolującymi chciwość np (?)
Wiec sie pytam czy to pytanie czy to stwierdzenie (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
wookieb
post
Post #10





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Stwierdzenie, że nie możesz go używać (IMG:style_emoticons/default/snitch.gif)
Go to the top of the page
+Quote Post
nospor
post
Post #11





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




why, wookieb why?
Go to the top of the page
+Quote Post
wookieb
post
Post #12





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Dobra może powiedz mi po co chcesz to zrobić? Wiesz, że mój parser bbcode można użyć do innych parserów zmieniając tylko ustawienia?

A dlaczego nie możesz, ponieważ wtedy preg_replace_callback nie będzie w stanie rekurencyjnie wyszukać START i END w tekście bo nigdy nie wystąpi 2x END oraz 2x START w dopasowanym ciągu.
Go to the top of the page
+Quote Post
kreciko
post
Post #13





Grupa: Zarejestrowani
Postów: 99
Pomógł: 7
Dołączył: 17.02.2010

Ostrzeżenie: (0%)
-----


Cytat(wookieb @ 28.09.2010, 10:08:45 ) *
Nie możesz się posługiwać operatorami kontrolującymi chciwość np (?)

To pytanie chyba było skierowane do mnie, ponieważ ja je(operator chciwości) pominąłem z powodu niewiedzy. Mea culpa.

Ten post edytował kreciko 28.09.2010, 09:35:11
Go to the top of the page
+Quote Post
nospor
post
Post #14





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Dobra może powiedz mi po co chcesz to zrobić?
for money (IMG:style_emoticons/default/winksmiley.jpg)
No jak to po co? Zeby działało (IMG:style_emoticons/default/smile.gif)

Cytat
A dlaczego nie możesz, ponieważ wtedy preg_replace_callback nie będzie w stanie rekurencyjnie wyszukać START i END w tekście bo nigdy nie wystąpi 2x END oraz 2x START w dopasowanym ciągu.
Ok. Moze się pobawie tym callbackiem
Go to the top of the page
+Quote Post
wookieb
post
Post #15





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(nospor @ 28.09.2010, 10:33:16 ) *
for money (IMG:style_emoticons/default/winksmiley.jpg)
No jak to po co? Zeby działało (IMG:style_emoticons/default/smile.gif)

To może tak. Jaką funkcjonalność chcesz stworzyć?
Go to the top of the page
+Quote Post
nospor
post
Post #16





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Taką jak opisałem.

Obszedłem to troszke i mam rozwiązanie
  1. $text = 'START bla bla bla START blablaW END bla3 END inneblabla START ccc xxx END inneblabla';
  2. $text = preg_replace('/^\s*START\s/s','',$text);
  3. $text = preg_replace('/START(\s+.*?\s+)END/s','#START#\\1#END#',$text);
  4. $text = 'START '.$text;
  5. $text = preg_replace('/^START\s+.*?\s+END/s','#zamienione#',$text);
  6. $text = str_replace(array('#START#','#END#'),array('START','END'),$text);
  7. echo $text;
Go to the top of the page
+Quote Post
Noidea
post
Post #17





Grupa: Zarejestrowani
Postów: 226
Pomógł: 61
Dołączył: 20.08.2010

Ostrzeżenie: (0%)
-----


@nospor
Twój kod sypnie się, jeśli START END będzie zagnieżdżone więcej niż 2 razy. Jeśli się to nigdy nie zdarzy, to OK, ale jeśli ma to działać w każdych warunkach, to lepiej jest wykorzystać tak zwane "recursive subpatterns". Działa to tak samo jak zwykła rekurencja (?R), tyle że nie wstawia tam całego oryginalnego wyrażenia, tylko n-ty nawias okrągły. A zapis jest taki: (?1), (?2), (?n)

  1. <?php
  2.  
  3. $text = 'START aa START bb START cc START dd END c END b START cc2 END b2 END a END inneblabla START xxx START yyy END zzz END inneblabla';
  4.  
  5. echo preg_replace( "~^(START\b((?1)|.)*?\bEND\b)~s", "#zamienione#", $text );
  6.  
  7. ?>
Go to the top of the page
+Quote Post
nospor
post
Post #18





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
wój kod sypnie się, jeśli START END będzie zagnieżdżone więcej niż 2 razy. Jeśli się to nigdy nie zdarzy, to OK
Tak, wiem o tym. Z założenie nie będzie jednak takiej sytuacji

Cytat
to lepiej jest wykorzystać tak zwane "recursive subpatterns". Działa to tak samo jak zwykła rekurencja (?R), tyle że nie wstawia tam całego oryginalnego wyrażenia, tylko n-ty nawias okrągły. A zapis jest taki: (?1), (?2), (?n)
Działa wyśmienicie, dzięki (IMG:style_emoticons/default/smile.gif)
Muszę poczytać o tych rekursywnych wyrażeniach bo próbuje przetrawić ten kod co podales i za chiny go nie kumam (IMG:style_emoticons/default/smile.gif)
Jeszcze gdzie jakiego backdora mi wlozyles (IMG:style_emoticons/default/winksmiley.jpg)

edit: i już chyba kumam (IMG:style_emoticons/default/smile.gif)

Z ciekawości zrobiłem testy czasowe.
Wyrażenie regularne jest szybsze od moich "kwiatków" (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
Noidea
post
Post #19





Grupa: Zarejestrowani
Postów: 226
Pomógł: 61
Dołączył: 20.08.2010

Ostrzeżenie: (0%)
-----


Ogólnie to:
1: Dopasuj START
2: Najpierw spróbuj dopasować całe zagnieżdżone START(...)END (rekurencja, GOTO 1: ), a jeśli się nie uda to:
3: Dopasuj jeden znak (kropka)
4: Jeśli napotkałeś END to zakończ, w przeciwnym razie GOTO 2:


EDIT:
No ty w swoich kwiatkach też masz wyrażenia regularne (IMG:style_emoticons/default/smile.gif)
W dodatku ślamazarność wyrażeń to trochę mit. To znaczy często, jeśli porównujemy regexp z całą masą substr w pętli to okazuje się, że ciągłe kopiowanie stringa w inne miejsca w pamięci daje taki narzut, że wyrażenia okazują się szybsze (IMG:style_emoticons/default/smile.gif)

Ten post edytował Noidea 28.09.2010, 11:33:49
Go to the top of the page
+Quote Post
nospor
post
Post #20





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
No ty w swoich kwiatkach też masz wyrażenia regularne
No tak.... czy już dziś piątek czy jak :/
Go to the top of the page
+Quote Post
Methestel
post
Post #21





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

Ostrzeżenie: (0%)
-----


Chcesz robić walidacja poprawności tekstu (czy liczba START-ów jest równa licznie END-ów)?
Go to the top of the page
+Quote Post
nospor
post
Post #22





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Nie wiem jak bardzo trzeba po chinsku czytac by dojsc do takiego wniosku (IMG:style_emoticons/default/winksmiley.jpg)
Poza tym wydaje mi się, iż jestem na takim etapie iż wiem jak policzyć w tekście liczbę dwóch słów i porównać te liczby ze sobą (IMG:style_emoticons/default/winksmiley.jpg)
Problem juz rozwiązany
Go to the top of the page
+Quote Post
Methestel
post
Post #23





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

Ostrzeżenie: (0%)
-----


Nie doszedłem do takiego wniosku tylko zapytałem czy nie potrzebujesz walidacji bo niedawno sam musiałem zmierzyć się z problemem niepoprawnie zbudowanego tekstu ze znacznikami (np częściowo ucięty XML). Przepraszam, że chciałem podzielić się doświadczeniami :/

Ten post edytował Methestel 28.09.2010, 20:09:26
Go to the top of the page
+Quote Post
nospor
post
Post #24





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Przepraszam, że chciałem podzielić się doświadczeniami
No ale chyba nie będziesz latał teraz po różnych tematach i nie pytał każdego czy nie chce usłyszeć jak zrobić coś tam bo akurat to przerabiałeś (IMG:style_emoticons/default/winksmiley.jpg)

Nie zrozum mnie źle: dzielenie się doświadczeniem to fajna sprawa i jak najbardziej to popieram ale rób to we właściwym miejscu i nie wyskakuj ni stąd ni zowąd ludziom w tematach z czymś takim. Poza tym źle zrozumiałem Twojego posta i myslalem że ty źle zrozumiales i wymyslasz jakieś inne rozwiązanie (IMG:style_emoticons/default/winksmiley.jpg)
Powód edycji: [nospor]:
Go to the top of the page
+Quote Post
Methestel
post
Post #25





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

Ostrzeżenie: (0%)
-----


Nie będe
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 14.09.2025 - 14:46