Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] Podmiana znaków w tekście - preg_replace + array
miki3475
post 27.07.2010, 17:08:42
Post #1





Grupa: Zarejestrowani
Postów: 58
Pomógł: 1
Dołączył: 15.06.2008

Ostrzeżenie: (10%)
X----


Witam, pracuję nad prostym skryptem, który pozwoli mi zakodować tekst używając mojego własnego kryptogramu.

Polegało będzie to na tym że skrypt ma za zadanie pozmieniać litery na swoje odpowiedniki (jakie mu wskaże) oraz obrócić tekst przy pomocy funkcji strrev (co akurat skomplikowane nie jest).


Przygotowałem następujący skrypt:


  1. <?php
  2. $string = 'Wawa';
  3. $patterns = array();
  4. $patterns[0] = '/W/';
  5. $patterns[1] = '/a/';
  6. $patterns[2] = '/w/';
  7. $replacements = array();
  8. $replacements[2] = 'a';
  9. $replacements[1] = 'G';
  10. $replacements[0] = '2';
  11. echo preg_replace($patterns, $replacements, $string);
  12. ?>


Prawidłową odpowiedzią na "Wawa" powinno być "aG2G", a otrzymuję "GG2G".

Jak widać problem dotyczy tego że po zamienieniu, stara się zamienić jeszcze raz, czyli:

W -> a -> G
A powinno być tylko:
W -> a

Próbowałem wprowadzić $limit = 1, jednak to się nie sprawdza do końca ponieważ wtedy otrzymujemy "Ga2a", czyli a nie jest już zamieniane bo zostało już raz zamienione.

Niektórzy powiedzą że nie możesz wprowadzić liter których tutaj nie ma?
Nie, bo chce zrobić tak z całym alfabetem, czyli nie da się tego tak ustawić aby się nie powtarzało winksmiley.jpg

Z góry dziękuję za pomoc

Ten post edytował miki3475 27.07.2010, 17:10:51
Go to the top of the page
+Quote Post
t4keda
post 27.07.2010, 17:28:10
Post #2





Grupa: Zarejestrowani
Postów: 57
Pomógł: 10
Dołączył: 14.10.2009

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


Może iteracja przez string ci się przyda?
Podobny temat: http://forum.php.pl/index.php?showtopic=81176
Go to the top of the page
+Quote Post
miki3475
post 27.07.2010, 17:36:13
Post #3





Grupa: Zarejestrowani
Postów: 58
Pomógł: 1
Dołączył: 15.06.2008

Ostrzeżenie: (10%)
X----


Cytat(t4keda @ 27.07.2010, 18:28:10 ) *
Może iteracja przez string ci się przyda?
Podobny temat: http://forum.php.pl/index.php?showtopic=81176


Z tego co widze to chodzi o to że się czynność powtarza, a ja tak jak piszę tego nie chce, chce żeby literka raz się zamieniła i koniec.
Ale dzięki za chęci winksmiley.jpg
Go to the top of the page
+Quote Post
Neeke
post 27.07.2010, 17:43:57
Post #4





Grupa: Zarejestrowani
Postów: 124
Pomógł: 16
Dołączył: 22.02.2007
Skąd: Warszawa

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


Poczytaj o wyrażeniach regularnych sporo tego jest na internecie
Go to the top of the page
+Quote Post
miki3475
post 27.07.2010, 17:56:34
Post #5





Grupa: Zarejestrowani
Postów: 58
Pomógł: 1
Dołączył: 15.06.2008

Ostrzeżenie: (10%)
X----


Cytat(Neeke @ 27.07.2010, 18:43:57 ) *
Poczytaj o wyrażeniach regularnych sporo tego jest na internecie


Ale że jak : o

Czy naprawdę jest konieczność skłaniania się do tak skomplikowanych rzeczy jakimi są wyrażenia regularne ;p
Czytałem kilkanaście razy kiedyś i nie wydaje mi się żeby to się przydało, bo przecież jak?

Tutaj chodzi o podmianę litery a do b, a nie określenie czy litera a to naprawdę litera a itp. Albo wyciąg litery ze zdania.
Go to the top of the page
+Quote Post
t4keda
post 27.07.2010, 18:03:23
Post #6





Grupa: Zarejestrowani
Postów: 57
Pomógł: 10
Dołączył: 14.10.2009

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


Cytat(miki3475 @ 27.07.2010, 18:36:13 ) *
Z tego co widze to chodzi o to że się czynność powtarza, a ja tak jak piszę tego nie chce, chce żeby literka raz się zamieniła i koniec.
Ale dzięki za chęci winksmiley.jpg


No tak czynność (podmiana czy co tam chcesz) się powtarza, ale dla każdej jednej litery z ciągu tylko raz. Dla tego przykładu:
  1. <?php
  2. header ('Content-Type:text/html; charset=utf-8');
  3.  
  4. $str = 'zażółć gęślą jaźń';
  5. print '$str: '.$str.'<br />';
  6. for($i = 0; $i < iconv_strlen($str, 'UTF-8'); $i++){
  7. print ' <br />'.iconv_substr($str, $i, 1, 'UTF-8').'<br />';
  8. }
  9. print '<br />$str: '.$str.'<br />';
  10. ?>


Każda litera powinna być w oddzielnej linii (albo nawet w co drugiej).
http://ideone.com/BwG8H
Go to the top of the page
+Quote Post
miki3475
post 27.07.2010, 18:20:36
Post #7





Grupa: Zarejestrowani
Postów: 58
Pomógł: 1
Dołączył: 15.06.2008

Ostrzeżenie: (10%)
X----


Ok, znalazłem odpowiedź w Manualu, skrypt jest dużo prostrzy, i ostatecznie wygląda tak:

  1. <?php
  2.  
  3. function stro_replace($search, $replace, $subject)
  4. {
  5. return strtr( $subject, array_combine($search, $replace) );
  6. }
  7. $search = array('W', 'a', 'w');
  8. $replace = array('a', 'G', 'Q');
  9. $subject = 'Wawa';
  10.  
  11. echo stro_replace($search, $replace, $subject);
  12. ?>


Dzięki wszystkim za pomoc winksmiley.jpg

Ten post edytował miki3475 27.07.2010, 19:52:37
Go to the top of the page
+Quote Post
thek
post 27.07.2010, 21:49:11
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




To ja Ci wyjaśnię dlaczego tak się działo. Mianowicie replace leci zawsze po kolei w swoich wzorcach. Jeśli więc się zdarzy, że któryś z kroków wcześniejszych zamieni fragment na taki, który wystąpi jako wzorzec później, to dopasuje się on do kolejnego wzorca i znów zamieni. Preg_match nie przerywa po pierwszym dopasowaniu, tylko leci dalej. Utworzy się więc łańcuch zmian, co zazwyczaj prowadzi do nieoczekiwanych wyników. Tak właśnie było w Twoim wypadku.
Inna sprawa, że w przykładzie będącym w Twoim pierwszym poście masz błąd, o czym prawdopodobnie nawet nie wiesz. $pattern[0] bowiem nie sparuje się z $replacement[0] (co wydawałoby się logiczne), tylko z $replacement[2]. Tak... Nie przewidziałeś się smile.gif Parują się elementy nie według klucza a kolejności podania ich dla funkcji, tak więc 0(W) => 2(a), 1()a => 1(G), 2(w) => 0(2). Teraz popatrz na każdy krok dla słowa "Wawa"
Przejście 1 wzorca -> W => a da nam: aawa
Przejście 2 wzorca -> a => G da nam: GGwG
Przejście 3 wzorca -> w => 2 da nam: GG2G
Popatrz no.... Dokładnie to co Ci wyszło jako błąd winksmiley.jpg Ja Ci zrobiłem to co preg_match, krok po kroku. Wiele osób się dziwi bo nie rozumie jak preg_match działa i przez to piszą złe reguły, choć logicznie są one prawidłowe. Ale logika ta nie wyklucza błędu na poziomie implementacji przez sam język. Trzeba po prostu wiedzieć, że należy tak pisać regułę, aby nie nastąpiło wielokrotne wymienienie w wyniku kolejnego sprawdzania podanych wzorców.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
miki3475
post 27.07.2010, 22:14:34
Post #9





Grupa: Zarejestrowani
Postów: 58
Pomógł: 1
Dołączył: 15.06.2008

Ostrzeżenie: (10%)
X----


Cytat(thek @ 27.07.2010, 22:49:11 ) *
To ja Ci wyjaśnię dlaczego tak się działo. Mianowicie replace leci zawsze po kolei w swoich wzorcach. Jeśli więc się zdarzy, że któryś z kroków wcześniejszych zamieni fragment na taki, który wystąpi jako wzorzec później, to dopasuje się on do kolejnego wzorca i znów zamieni. Preg_match nie przerywa po pierwszym dopasowaniu, tylko leci dalej. Utworzy się więc łańcuch zmian, co zazwyczaj prowadzi do nieoczekiwanych wyników. Tak właśnie było w Twoim wypadku.
Inna sprawa, że w przykładzie będącym w Twoim pierwszym poście masz błąd, o czym prawdopodobnie nawet nie wiesz. $pattern[0] bowiem nie sparuje się z $replacement[0] (co wydawałoby się logiczne), tylko z $replacement[2]. Tak... Nie przewidziałeś się smile.gif Parują się elementy nie według klucza a kolejności podania ich dla funkcji, tak więc 0(W) => 2(a), 1()a => 1(G), 2(w) => 0(2). Teraz popatrz na każdy krok dla słowa "Wawa"
Przejście 1 wzorca -> W => a da nam: aawa
Przejście 2 wzorca -> a => G da nam: GGwG
Przejście 3 wzorca -> w => 2 da nam: GG2G
Popatrz no.... Dokładnie to co Ci wyszło jako błąd winksmiley.jpg Ja Ci zrobiłem to co preg_match, krok po kroku. Wiele osób się dziwi bo nie rozumie jak preg_match działa i przez to piszą złe reguły, choć logicznie są one prawidłowe. Ale logika ta nie wyklucza błędu na poziomie implementacji przez sam język. Trzeba po prostu wiedzieć, że należy tak pisać regułę, aby nie nastąpiło wielokrotne wymienienie w wyniku kolejnego sprawdzania podanych wzorców.


Hmm, ok postaram się coś wynieść z tej lekcji winksmiley.jpg

Wszystkim dzięki, encoder działa b. dobrze ;p
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 15.07.2025 - 04:11