Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Wulgaryzmy i wyjątki
Forum PHP.pl > Forum > Przedszkole
Szunaj85
Mam formularz w którym weryfikuję za pomocą skryptu treść wyszukując w niej wulgaryzmów. Skrypt to tablica w której znajdują się wulgaryzmy oraz pętla, która sprawdza czy w tekście są wulgaryzmy.
Problem w tym, że są słowa które same w sobie zawierają ciąg znaków odpowiadający wulgaryzmowi, np. cham - słucham.
Skrypt takie słowa również bierze za wulgaryzmy.
Jeśli chodzi o rozwiązanie myślę tu o stworzeniu drugiej tablicy wyjątków, ale nie wiem jak to dalej zrobić. A może jest jakiś lepszy sposób?
Crozin
Ty mi lepiej powiedz od kiedy to "cham" to wulgaryzm? Kurwy, chuje i inne popierdoleńce to rozumiem, ale by chama cenzurować? W ogóle próba cenzury jest kompletnie bezsensowna, bo:
1. Cenzura to zło.
2. Jeżeli nawet jest "k*rwa" czy "k***a" i tak każdy przeczyta to "kurwa".
3. Jeżeli spróbujesz uniemożliwić dodanie treści z wulgaryzmami to i tak ktoś napisze "k u r w a" czy coś w ten deseń czego na 99% nie wychwycisz. Za to na pewno po przeczytaniu komunikatu "prosimy o dodawanie treści bez przekleństw" nie zrezygnuje z dodania ich.
sadistic_son
Hehe Szunaj zapewne miał na myśli takie słowa jak wymieniłeś ale nie chciał ich bezkarnie pisać na forum żeby kicka nie dostać ;P Ale Ty crozin za to ładnie popłynąłeś biggrin.gif
Crozin
@sadistic_son: W temacie o wulgaryzmach raczej ciężko uniknąć przykładu wulgaryzmów czy odwoływania się do nich. Jeżeli temat dotyczy tych nieszczęsnych kurw i podobnych to piszemy "kurwa". Przecież ja tu nikogo nie obrażam. Pamiętaj... nadgorliwość jest gorsza od faszyzmu. wink.gif

A wracając do tematu. Jeżeli już zdecydujesz się na tą durną cenzurę to po prostu sprawdź czy ów słowo nie stoi w sąsiedztwie innych znaków alfabetycznych. Innymi słowy: jeżeli przed lub po wyrazie jest np. "ą", "s" albo "t" to zostaw. Natomiast jeżeli masz ".", " " (spacja) czy koniec ciągu to ocenzuruj.
Szunaj85
Cytat
Ty mi lepiej powiedz od kiedy to "cham" to wulgaryzm? Kurwy, chuje i inne popierdoleńce to rozumiem, ale by chama cenzurować? W ogóle próba cenzury jest kompletnie bezsensowna, bo:
1. Cenzura to zło.
2. Jeżeli nawet jest "k*rwa" czy "k***a" i tak każdy przeczyta to "kurwa".
3. Jeżeli spróbujesz uniemożliwić dodanie treści z wulgaryzmami to i tak ktoś napisze "k u r w a" czy coś w ten deseń czego na 99% nie wychwycisz. Za to na pewno po przeczytaniu komunikatu "prosimy o dodawanie treści bez przekleństw" nie zrezygnuje z dodania ich.
Oczywiście znam te wszystkie sposoby omijania, więc nie musisz mi tego uświadamiać.
Cytat
Hehe Szunaj zapewne miał na myśli takie słowa jak wymieniłeś ale nie chciał ich bezkarnie pisać na forum żeby kicka nie dostać
Dokładnie, podałem tylko przykład chcąc jednocześnie zbytnio nie przeklinać.
Cytat
Jeżeli już zdecydujesz się na tą durną cenzurę to po prostu sprawdź czy ów słowo nie stoi w sąsiedztwie innych znaków alfabetycznych
Mógłbyś podać jakiś przykład? Jakich funkcji do tego użyć?
peter13135
@Crozin
Ale Twój sposób jest średnio dobry, bo takie słowo jak 'nie podsłuchuj' przejdzie przez cenzurę, ale przejdą przekleństwa 'pochodne' jak chujowy itp.
Crozin
@peter13135: Po prostu baza wulgaryzmów musiałby zawierać przekleństwa również w formach odmienionych. Język polski nie jest tutaj zbyt przyjazny, ale co poradzisz... wink.gif

@Szunaj85:
Tak na szybko (nie testowane)
  1. $text = 'Kurwa! Nie podsłuchuj. Kurwa!';
  2.  
  3. $forbiddenWords = array('kurwa', 'chuj');
  4.  
  5. // Bardzo proste obejście problemu początku i końca tekstu
  6. $text = '#' . $text . '#';
  7.  
  8. $forbiddenWords = implode('|', $forbiddenWords);
  9. $text = preg_replace_callback('/[^\pL](?:' . $forbiddenWords . ')[^\pL]/ius', function($matches) {
  10. // $matches[0] = #Kurwa!
  11.  
  12. // #K
  13. $return = mb_substr($matches[0], 0, 2);
  14.  
  15. // #K***
  16. $return .= str_repeat('*', mb_strlen($matches[0]) - 4);
  17.  
  18. // #K***a!
  19. $return .= mb_substr($matches[0], -2);
  20.  
  21. return $return;
  22. }, $text);
  23.  
  24. // Powrót do pierwotnego tekstu (bez "#")
  25. $text = mb_substr($text, 1, -1);
  26.  
  27. echo $text;
Szunaj85
Crozin ja nie chcę cenzurować i zamieniać znaki na **** tylko wykrywać przekleństwa. Z wykryciem tak jak wcześniej pisałem nie mam problemu, chodzi głównie o te nieszczęsne słowa zawierające przekleństwo w sobie.
Magic WWW
Najprostszym sposobem jest sprawdzenie czy przed i po danym słowie nie znajduje się jakaś litera, można takie coś skonstruować za pomocą wyrażeń regularnych.
Crozin
@Szunaj85: To zamiast preg_replace_callback, które zmienia zawartość zmiennej użyj preg_match, które po prostu wyszuka i zwróci ilość wystąpień znalezionych wulgaryzmów.
Szunaj85
Cytat
@Crozin
Ale Twój sposób jest średnio dobry, bo takie słowo jak 'nie podsłuchuj' przejdzie przez cenzurę, ale przejdą przekleństwa 'pochodne' jak chujowy itp.
Cytat
Najprostszym sposobem jest sprawdzenie czy przed i po danym słowie nie znajduje się jakaś litera, można takie coś skonstruować za pomocą wyrażeń regularnych.
No niestety tutaj się muszę zgodzić z peter13135. Dla części wyjątków to zadziała, ale dla reszty już nie.
Cytat
To zamiast preg_replace_callback, które zmienia zawartość zmiennej użyj preg_match, które po prostu wyszuka i zwróci ilość wystąpień znalezionych wulgaryzmów.
Tylko, że mój problem tego nie dotyczy.
Otto
Zabronić słowa kur*a to tak jak by zabrać połowę słownika... Wyraża więcej niż tysiąc słów.
everth
@Szunaj85 - zainteresuj się funkcjami wyliczającymi podobieństwo dwóch ciągów lub odległością Levenshteina (obie wbudowane w PHP) przy porównywaniu słów do wzorca. Powinno ci się udać wychwycić najczęstsze metody omijania takie jak zastąpienie znaku w wyrazie czy zamiana miejscami liter (ludzki umysł jest tak skonstruowany że patrzy na początek i koniec słowa dopasowując resztę do wzorca). Przy czym tekst musisz w jakiś sposób podzielić na słowa - np. regexem po spacjach/tabulatorach/znakach końca linii. Zabezpieczeniem przed k u r w a może być to że jednoliterowych spójników w języku polskim jest tylko parę - więc poza nimi samotne litery można spokojnie wycinać. Możesz też kombinować z funkcjami dodatku pSpell przy wyszukiwaniu "podejrzanych" słów.

Powyższe nie zmienia faktu że wszelkie wysiłki skierowane na wykrywanie przekleństw na dłuższą metę skazane są na porażkę. Człowiek jest bardziej kreatywny od maszyny więc w końcu coś przecieknie przez twój filtr (jakkolwiek wyszukany by on nie był).
Szunaj85
Cytat(everth)
Powyższe nie zmienia faktu że wszelkie wysiłki skierowane na wykrywanie przekleństw na dłuższą metę skazane są na porażkę. Człowiek jest bardziej kreatywny od maszyny więc w końcu coś przecieknie przez twój filtr
Czy to co wcześniej napisałem jest nie zrozumiałe? Ja nie chcę cenzurować, nie chcę zamieniać przekleństwa na gwiazdki. W pierwszym poście jest napisane w czym problem!
Cytat(Magic WWW)
Najprostszym sposobem jest sprawdzenie czy przed i po danym słowie nie znajduje się jakaś litera, można takie coś skonstruować za pomocą wyrażeń regularnych.
A mógłbyś mi pomóc? Bo z wyrażeń regularnych jestem dość słaby. Jakiś przykład by się przydał.
Crozin
@Szunaj85: Kod, który podałem jest tym o co teraz prosisz. Jedynie wywal z niego fragment cenzurujący (zmieniający na gwiazdki), a zamiast tego sprawdź ile odnaleziono wyników. Innymi słowy: skorzystaj z preg_match[_all] zamaist preg_replace.
Szunaj85
  1. $text = 'Kurwa! Nie podsłuchuj. Kurwa!';
  2.  
  3. $forbiddenWords = array('kurwa', 'chuj');
  4.  
  5. // Bardzo proste obejście problemu początku i końca tekstu
  6. $text = '#' . $text . '#';
  7.  
  8. $forbiddenWords = implode('|', $forbiddenWords);
  9. $text = preg_match('/[^\pL](?:' . $forbiddenWords . ')[^\pL]/ius', function($matches) {
  10. // $matches[0] = #Kurwa!
  11.  
  12. return $return;
  13. }, $text);
  14.  
  15. // Powrót do pierwotnego tekstu (bez "#")
  16. $text = mb_substr($text, 1, -1);
  17.  
  18. echo $text;
Aj, mimo moich prób skrypt nie działa. W dodatku w 9 linii wyskakuje błąd. Pomożecie mi poprawić błędy?
Crozin
preg_match oczekuje jedynie dwóch argumentów: wyrażenia i przeszukiwanego ciągu. Co więcej funkcja ta zwróci Ci 0 albo 1 oznaczające kolejno nie znaleziono i znaleziono.
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.