Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Cenzura
Forum PHP.pl > Forum > Przedszkole
marcin0077
Witam

Mam shoutboxa i zrobiona cenzurę. Cenzuruję wpisane słowa ale chciałbym zrobić ze np po znalezieniu zakazanego słowa skrypt cenzurował całą wiadomość.
Może ktoś pomóc?

kod cenzury

  1. function censor($str) {
  2. global $prefs;
  3.  
  4. $cWords = explode(',', $prefs['censorWords']);
  5. $words = explode(' ', $str);
  6. $endings = '|ed|es|ing|s|er|ers';
  7. $arrEndings = explode('|', $endings);
  8.  
  9. foreach ($cWords as $cWord) foreach ($words as $i=>$word) {
  10. $pattern = '/^(' . $cWord . ')+(' . $endings . ')\W*$/i';
  11. $words[$i] = preg_replace($pattern, str_repeat('*', strlen($word)), $word);
  12. }
  13.  
  14. $i = implode(' ', $words);
  15. $cen = array('********');
  16. $a = str_replace($cen, "", $i);
  17. return $a;
  18. }
phpion
Spójrz na 4 parametr w str_replace. Jeżeli zwróci wartość większą od 0 to znaczy, że coś zostało ocenzurowane (czyli był wulgaryzm). W takiej sytuacji zwróć coś innego niż $a (np. pusty ciąg albo NULL).
marcin0077
przy zmianie parametru a$ zmienia wszystkie wiadomości te dobre też no chyba że ja coś źle robię

jakieś dalsze propozycje?
thek
Pytanie więc.. Czy Ty posyłasz do cenzury wszystkie wiadomości naraz? Bo z tego co piszesz tak wynika. Jeśli tak, to musisz zrobić rozgraniczenie na osobne wiadomości wpierw i dopiero je cenzurować. Inaczej nie wyłapiesz którą poddać całkowite cenzurze, a którą nie. Wtedy możesz zastosować wspomniany przez phpiona 4 parametr str_replace. Poza tym w podanym przez Ciebie kodzie zrobiłem mała poprawkę, bo przy przeklejaniu wcięło Ci zamykający apostrof za gwiazdkami. Miało być:
  1. $cen = array('********');

było
  1. $cen = array('********);
marcin0077
tak wszystkie słowa razem, wygląda to tak:

  1. $cen = array('słowo1', 'słowo2.', 'słowo3', 'słowo4', 'słowo5');


z tym apostrofem to moderator jak usuwał przekleństwo to usunął też apostrof smile.gif
to co phpion napisał to nie rozumiem - nie umiem sobie z tym poradzić

pomoże ktoś z tym rozdzieleniem bo patrze, czytam ale nie czaje zbytnio jak to zrobić
można by to rozdzielić na 2 grupy wiadomości które cenzuruje całe oraz wiadomości które cenzuruje tylko dane słowo
thek
Nie chodzi mi tutaj o to czy wszystkie słowa razem, bo to "rozumie się samo przez się". Pytałem się czy wszystkie wiadomości z shouta, czy tylko od pojedynczego usera. To co opisał phpion to rzadko używany 4 parametr wspomnianej funkcji. Zawiera on informację ile razy str_replace się wykonało w przetwarzanym ciągu. Jeśli w wyniku masz 0 to super - brak wulgaryzmow. Jeśli jest coś więcej to znaczy że wulgaryzm był. Jeśli censor jest uruchamiane dla każdej wiadomości z osobna to w wyniku wystarczy, że do zmiennej $a podepniesz informację, że wiadomość zawiera wulgaryzm i została ocenzurowana. jeśli censor od razu wszystkie wiadomości sprawdza to musisz tak kod zmodyfikować, by rozpoznawać osobne wiadomości.
Volume
hmm a ja nie rozumiem czemu cenzurowac cala widomosc jesli raz ktos uzuyje niecenzurowanego slowa, czasami trzeba ( ...;] ) no a jesli portal tak bardzo nie pochwala tego typu lacin niech funduje to tylko wspominanym str_replace..
Methestel
Pozwoliłem sobie zmierzyć się z problemem cenzury i osobiście rozwiązałbym to w ten sposób:

  1. /**
  2.  * Cenzura
  3.  * @param $content Tekst do cenzury
  4.  * @param $censorshipPatternsArr Tablica tablic asocjacyjnych z polami: pattern, replace
  5.  * @param &$count Ilość ocenzurowanych słów
  6.  * @return Ocenzurowany tekst
  7.  */
  8. function censorship($content, $censorshipConfig, &$count = 0) {
  9. $count = 0;
  10. for ($i = 0, $max = count($censorshipConfig), $n = 0; $i < $max; $i++, $count += $n, $n = 0) {
  11. $pattern = $censorshipConfig[$i]['pattern'];
  12. $replace = $censorshipConfig[$i]['replace'];
  13. $content = preg_replace($pattern, $replace, $content, -1, $n);
  14. }
  15. return $content;
  16. }


Przykład użycia:
  1. $config = array(
  2. array('pattern' => '/admin(\W+)/si', 'replace' => 'bóg$1'),
  3. array('pattern' => '/Admin(\w+)/s', 'replace' => 'Bog$1'),
  4. array('pattern' => '/admin(\w+)/si', 'replace' => 'bog$1'),
  5. array('pattern' => '/m\W*o\W*t\W*y\W*l\W*a\W*n\W*o\W*g\W*a/si', 'replace' => '!@#$'),
  6. array('pattern' => '/ktury(\w+)/si', 'replace' => 'który$1')
  7. );
  8.  
  9. $text = 'Motyla noga!!! admin musi zbanować ten tekst. MoTyla.NoGa!!!. Adminowi się nie chce tego robić ręcznie. M.O.T.Y.L.A N.O.G.A!';
  10. $count = 0;
  11.  
  12. echo 'Przed: '.$text.'<br />';
  13. echo 'Po: '.censorship($text, $config, $count).'<br />';
  14. echo 'Ocenzurowano wyrazów: '.$count;


Wynik:
  1. Przed: Motyla noga!!! admin musi zbanować ten tekst. MoTyla.NoGa!!!. Adminowi się nie chce tego robić ręcznie. M.O.T.Y.L.A N.O.G.A!
  2. Po: !@#$!!! bógmusi zbanować ten tekst. !@#$!!!. Bogowi się nie chce tego robić ręcznie. !@#$!
  3. Ocenzurowano wyrazów: 5


Moim skromnym zdaniem jest to rozwiązanie proste i bardzo elastyczne i prawdopodobnie wydajniejsze od twojego. Polecam smile.gif
thek
Jego rozwiązanie jest dobre... dla języka angielskiego (chodzi o końcówki) smile.gif Z polskim sprawuje się nieco gorzej. Twój sposób Methestel to niestety masa wpisów i masa wyrażeń regularnych do wykonania. Każdy wyraz to byłoby osobne a przy kilkuset już byłoby zapewne odczuwalne to, nie mówiąc o tysiącach smile.gif Nie wyobrażam sobie ręcznego ustawiania tego wszystkiego, pisania tych wszystkich wyrażeń. To co proponujesz jest już bliższe Tezaurusowi niż prostemu cenzurowaniu.
marcin0077
Cytat(Volume @ 15.03.2010, 23:06:42 ) *
hmm a ja nie rozumiem czemu cenzurowac cala widomosc jesli raz ktos uzuyje niecenzurowanego slowa, czasami trzeba ( ...;] ) no a jesli portal tak bardzo nie pochwala tego typu lacin niech funduje to tylko wspominanym str_replace..


chodzi mi bardziej o cenzurę adresów www dlatego jak ktoś wpisze coś co zawiera http, www, .pl, .com, .eu itd. to żeby cenzurowało cała wiadomość
thek
No to tu już najlepsze wyrażenia regularne wyszukujące adresu smile.gif Znajdzie takowy - wstawia zamiast tego http://tu_był_link czy coś w ten deseń.
marcin0077
Cytat(thek @ 16.03.2010, 14:17:04 ) *
No to tu już najlepsze wyrażenia regularne wyszukujące adresu smile.gif Znajdzie takowy - wstawia zamiast tego http://tu_był_link czy coś w ten deseń.


tylko w tym momencie jak będzie taki tekst:
Super Gry, Programy, Filmy, Porno tylko w http://www.jakas_strona.pl to wymoderuje sam adres a opis zostanie
a poza tym w cenzurze mogę sobie zrobić różne kombinacje takie jak: www, w_w_w, w w w, w.w.w, w,w,w itd. bo takich kombinacji też będzie a nie wiem jak to z tymi wyrażeniami hmm?
Methestel
Cytat(thek @ 16.03.2010, 09:16:51 ) *
Jego rozwiązanie jest dobre... dla języka angielskiego (chodzi o końcówki) smile.gif Z polskim sprawuje się nieco gorzej. Twój sposób Methestel to niestety masa wpisów i masa wyrażeń regularnych do wykonania. Każdy wyraz to byłoby osobne a przy kilkuset już byłoby zapewne odczuwalne to, nie mówiąc o tysiącach smile.gif Nie wyobrażam sobie ręcznego ustawiania tego wszystkiego, pisania tych wszystkich wyrażeń. To co proponujesz jest już bliższe Tezaurusowi niż prostemu cenzurowaniu.


Regexp-y wykonywane są na całej wypowiedzi, nie na poszczególnych wyrazach dzięki czemu ilość regexp-ów zmniejsza się (a nie zwiększa) i to dość znacznie. Powiedzmy że mamy wypowiedz złożoną z 100 wyrazów. Cenzurujemy powiedzmy 5 wyrazów. U kolegi wykona się łącznie 500 regexp-ów (zagnieżdzona pętla foreach) u mnie za to tylko 5.
Ustawianie tego jest tak samo trudne jak u kolegi. Jeśli chcę cenzurować n słów to będę miał n wpisów. W przykładzie poza cenzurowaniem pokazane są też inne możliwości jakie daje moje rozwiązanie tj. zamiana tekstu, poprawianie typowych błędów. W bardzo łatwy sposób można też dodać to czego kolega potrzebuje czyli cenzurowanie linków w tekstach. No i na koniec to na czym koledze zależało czyli licznik ocenzurowanych słów.

Proponuje jeszcze raz przeanalizować obydwa rozwiązania.



thek
Tak, ale u Ciebie także. Jakim cudem? Ano takim, że ma on przykładowo X słów z Y końcówkami. Słówko "cod" zostanie sprawdzone pod kątem występowania jako słowa:
cod, coded, codes, coding, cods, coder, coders
A co u Ciebie? Ty każde z nich piszesz jako osobny regexp (!) Nadal nie widzisz, że oba rozwiązania wcale nie są bardzo inne? Ja patrząc z boku tak to widzę. Ty jako użytkownik swojego rozwiązania tego nie zauważasz, zachłystując się rzekomo mniejszą ilością regexp. Ale to tylko złudzenie. Napisz teraz swoje tak, by objęło owo X wyrazów wraz z Y możliwymi końcówkami swoją metodą winksmiley.jpg Pochlastasz się przy pisaniu regexp numer 432 winksmiley.jpg
marcin0077
te końcówki można chyba zlikwidować łatwo i nie będzie z "regexpami" problemu
Methestel
Cytat(thek @ 16.03.2010, 20:29:41 ) *
Tak, ale u Ciebie także. Jakim cudem? Ano takim, że ma on przykładowo X słów z Y końcówkami. Słówko "cod" zostanie sprawdzone pod kątem występowania jako słowa:
cod, coded, codes, coding, cods, coder, coders
A co u Ciebie? Ty każde z nich piszesz jako osobny regexp (!) Nadal nie widzisz, że oba rozwiązania wcale nie są bardzo inne? Ja patrząc z boku tak to widzę. Ty jako użytkownik swojego rozwiązania tego nie zauważasz, zachłystując się rzekomo mniejszą ilością regexp. Ale to tylko złudzenie. Napisz teraz swoje tak, by objęło owo X wyrazów wraz z Y możliwymi końcówkami swoją metodą winksmiley.jpg Pochlastasz się przy pisaniu regexp numer 432 winksmiley.jpg

No i dalej nie przyjrzałeś się dokładnie rozwiązaniom smile.gif
Cytat
Ty każde z nich piszesz jako osobny regexp (!)

Oh, rly?
  1. $config = array(
  2. array('pattern' => '/(\W+)cod(|ed|es|ing|s|er|ers)(\W+)/si', 'replace' => '$1***$2$3 ')
  3. );

albo jeszcze lepiej (to załatwia wszystkie końcówki)
  1. $config = array(
  2. array('pattern' => '/(\W+)cod(|\w+)/si', 'replace' => '$1***$2')
  3. );

i sprawa załatwiona. Nie muszę rozbijać wypowiedzi na tablicę wyrazów przy pomocy explode() i nie muszę generować za każdym razem wyrażenia regularnego. Jeśli nadal chcesz się kłócić co jest szybsze możesz to przetestować. Jeśli nie będzie Ci się chciało a dalej będziesz pisał że w w moim rozwiązaniu wykonuje się więcej regeqpów po powrocie z roboty Ci to sam udowodnie smile.gif
Cytat
Napisz teraz swoje tak, by objęło owo X wyrazów wraz z Y możliwymi końcówkami swoją metodą winksmiley.jpg Pochlastasz się przy pisaniu regexp numer 432 winksmiley.jpg

Proszę bardzo:
  1. $config = array(
  2. array('pattern' => '/(\W+)wyraz_1(|\w+)/si', 'replace' => '$1*****$2'),
  3. array('pattern' => '/(\W+)wyraz_2(|\w+)/si', 'replace' => '$1*****$2'),
  4. array('pattern' => '/(\W+)wyraz_3(|\w+)/si', 'replace' => '$1*****$2'),
  5. array('pattern' => '/(\W+)wyraz_4(|\w+)/si', 'replace' => '$1*****$2'),
  6. array('pattern' => '/(\W+)wyraz_X(|\w+)/si', 'replace' => '$1*****$2')
  7. );
  8.  
  9. //albo
  10.  
  11. $config = array(
  12. array('pattern' => '/(\W+)(wyraz_1|wyraz_2|wyraz_3|wyraz_4|...|wyraz_X)(|\w+)/si', 'replace' => '$1*****$3'),
  13. );
  14.  


Jakoś można się wyrobić nawet w jednym regexpie smile.gif
Może po prostu nie do końca zdajesz sobie sprawę jakie możliwości dają wyrażenia regularne :/
marcin0077
odświeżam gdyż nadal nie wiem jak zrobić cenzurę na całe wiadomości
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.