Skip to content

Commit 2b1803d

Browse files
committed
релиз
1 parent f170385 commit 2b1803d

File tree

7 files changed

+396
-0
lines changed

7 files changed

+396
-0
lines changed

ObsceneCensorRus.php

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
<?php
2+
3+
class ObsceneCensorRus {
4+
public static $log;
5+
public static $logEx;
6+
7+
private static $LT_P = 'пПnPp';
8+
private static $LT_I = 'иИiI1u';
9+
private static $LT_E = 'еЕeE';
10+
private static $LT_D = 'дДdD';
11+
private static $LT_Z = 'зЗ3zZ3';
12+
private static $LT_M = 'мМmM';
13+
private static $LT_U = 'уУyYuU';
14+
private static $LT_O = 'оОoO0';
15+
private static $LT_L = 'лЛlL';
16+
private static $LT_S = 'сСcCsS';
17+
private static $LT_A = 'аАaA';
18+
private static $LT_N = 'нНhH';
19+
private static $LT_G = 'гГgG';
20+
private static $LT_CH = 'чЧ4';
21+
private static $LT_K = 'кКkK';
22+
private static $LT_C = 'цЦcC';
23+
private static $LT_R = 'рРpPrR';
24+
private static $LT_H = 'хХxXhH';
25+
private static $LT_YI = 'йЙy';
26+
private static $LT_YA = 'яЯ';
27+
private static $LT_YO = 'ёЁ';
28+
private static $LT_YU = 'юЮ';
29+
private static $LT_B = 'бБ6bB';
30+
private static $LT_T = 'тТtT';
31+
private static $LT_HS = 'ъЪ';
32+
private static $LT_SS = 'ьЬ';
33+
private static $LT_Y = 'ыЫ';
34+
35+
36+
public static $exceptions = array(
37+
'команд',
38+
'рубл',
39+
'премь',
40+
'оскорб',
41+
'краснояр',
42+
'бояр',
43+
'ноябр',
44+
'карьер',
45+
'мандат',
46+
'употр',
47+
'плох',
48+
'интер',
49+
'веер',
50+
'фаер',
51+
'феер',
52+
'hyundai',
53+
'тату',
54+
'браконь',
55+
'roup',
56+
'сараф',
57+
'держ',
58+
'слаб',
59+
'ридер',
60+
'истреб',
61+
'потреб',
62+
'коридор',
63+
'sound',
64+
'дерг',
65+
'подоб',
66+
'коррид',
67+
'дубл',
68+
'курьер',
69+
'экст',
70+
'try',
71+
'enter',
72+
'oun',
73+
'aube',
74+
'ibarg',
75+
'16',
76+
'kres',
77+
'глуб',
78+
'ebay',
79+
'eeb',
80+
'shuy',
81+
'ансам',
82+
'cayenne',
83+
'ain',
84+
'oin',
85+
'тряс',
86+
'ubu',
87+
'uen',
88+
'uip',
89+
'oup',
90+
'кораб',
91+
'боеп',
92+
'деепр',
93+
'хульс',
94+
'een',
95+
'ee6',
96+
'ein',
97+
'сугуб',
98+
'карб',
99+
'гроб',
100+
'лить',
101+
'рсук',
102+
'влюб',
103+
'хулио',
104+
'ляп',
105+
'граб',
106+
'ибог',
107+
'вело',
108+
'ебэ',
109+
'перв',
110+
'eep',
111+
);
112+
113+
public static function getFiltered($text, $charset = 'UTF-8') {
114+
self::filterText($text, $charset);
115+
return $text;
116+
}
117+
118+
public static function isAllowed($text, $charset = 'UTF-8') {
119+
$original = $text;
120+
self::filterText($text, $charset);
121+
return $original === $text;
122+
}
123+
124+
public static function filterText(&$text, $charset = 'UTF-8')
125+
{
126+
$utf8 = 'UTF-8';
127+
128+
if ($charset !== $utf8) {
129+
$text = iconv($charset, $utf8, $text);
130+
}
131+
132+
preg_match_all('/
133+
\b\d*(
134+
\w*[' . self::$LT_P . '][' . self::$LT_I . self::$LT_E . '][' . self::$LT_Z . '][' . self::$LT_D . ']\w* # пизда
135+
|
136+
(?:[^' . self::$LT_I . self::$LT_U . '\s]+|' . self::$LT_N . self::$LT_I . ')?(?<!стра)[' . self::$LT_H . '][' . self::$LT_U . '][' . self::$LT_YI . self::$LT_E . self::$LT_YA . self::$LT_YO . self::$LT_I . self::$LT_L . self::$LT_YU . '](?!иг)\w* # хуй; не пускает "подстрахуй", "хулиган"
137+
|
138+
\w*[' . self::$LT_B . '][' . self::$LT_L . '](?:
139+
[' . self::$LT_YA . ']+[' . self::$LT_D . self::$LT_T . ']?
140+
|
141+
[' . self::$LT_I . ']+[' . self::$LT_D . self::$LT_T . ']+
142+
|
143+
[' . self::$LT_I . ']+[' . self::$LT_A . ']+
144+
)(?!х)\w* # бля, блядь; не пускает "бляха"
145+
|
146+
(?:
147+
\w*[' . self::$LT_YI . self::$LT_U . self::$LT_E . self::$LT_A . self::$LT_O . self::$LT_HS . self::$LT_SS . self::$LT_Y . self::$LT_YA . '][' . self::$LT_E . self::$LT_YO . self::$LT_YA . self::$LT_I . '][' . self::$LT_B . self::$LT_P . '](?!ы\b|ол)\w* # не пускает "еёбы", "наиболее", "наибольшее"...
148+
|
149+
[' . self::$LT_E . self::$LT_YO . '][' . self::$LT_B . ']\w*
150+
|
151+
[' . self::$LT_I . '][' . /*self::$LT_P .*/ self::$LT_B . '][' . self::$LT_A . ']\w+
152+
|
153+
[' . self::$LT_YI . '][' . self::$LT_O . '][' . self::$LT_B . self::$LT_P . ']\w*
154+
) # ебать
155+
|
156+
\w*[' . self::$LT_S . '][' . self::$LT_C . ']?[' . self::$LT_U . ']+(?:
157+
[' . self::$LT_CH . ']*[' . self::$LT_K . ']+
158+
|
159+
[' . self::$LT_CH . ']+[' . self::$LT_K . ']*
160+
)[' . self::$LT_A . self::$LT_O . ']\w* # сука
161+
|
162+
\w*(?:
163+
[' . self::$LT_P . '][' . self::$LT_I . self::$LT_E . '][' . self::$LT_D . '][' . self::$LT_A . self::$LT_O . self::$LT_E/* . self::$LT_I*/ . ']?[' . self::$LT_R . '](?!о)\w* # не пускает "Педро"
164+
|
165+
[' . self::$LT_P . '][' . self::$LT_E . '][' . self::$LT_D . '][' . self::$LT_E . self::$LT_I . ']?[' . self::$LT_G . self::$LT_K . ']
166+
) # пидарас
167+
|
168+
\w*[' . self::$LT_Z . '][' . self::$LT_A . self::$LT_O . '][' . self::$LT_L . '][' . self::$LT_U . '][' . self::$LT_P . ']\w* # залупа
169+
|
170+
\w*[' . self::$LT_M . '][' . self::$LT_A . '][' . self::$LT_N . '][' . self::$LT_D . '][' . self::$LT_A . self::$LT_O . ']\w* # манда
171+
)\b
172+
/xu', $text, $m);
173+
174+
175+
$c = count($m[1]);
176+
177+
/*
178+
$exclusion=array('хлеба','наиболее');
179+
$m[1]=array_diff($m[1],$exclusion);
180+
*/
181+
182+
if ($c > 0) {
183+
for ($i = 0; $i < $c; $i++) {
184+
$word = $m[1][$i];
185+
$word = mb_strtolower($word, $utf8);
186+
187+
foreach (self::$exceptions as $x) {
188+
if (mb_strpos($word, $x) !== false) {
189+
if (is_array(self::$logEx)) {
190+
$t = &self::$logEx[$m[1][$i]];
191+
++$t;
192+
}
193+
$word = false;
194+
unset($m[1][$i]);
195+
break;
196+
}
197+
}
198+
199+
if ($word) {
200+
$m[1][$i] = str_replace(array(' ', ',', ';', '.', '!', '-', '?', "\t", "\n"), '', $m[1][$i]);
201+
}
202+
}
203+
204+
$m[1] = array_unique($m[1]);
205+
206+
//var_dump($m[1]);
207+
$asterisks = array();
208+
foreach ($m[1] as $word) {
209+
if (is_array(self::$log)) {
210+
$t = &self::$log[$word];
211+
++$t;
212+
}
213+
$asterisks []= str_repeat('*', mb_strlen($word, $utf8));
214+
}
215+
216+
$text = str_replace($m[1], $asterisks, $text);
217+
218+
if ($charset !== $utf8) {
219+
$text = iconv($utf8, $charset, $text);
220+
}
221+
222+
return true;
223+
} else {
224+
if ($charset !== $utf8) {
225+
$text = iconv($utf8, $charset, $text);
226+
}
227+
228+
return false;
229+
}
230+
}
231+
232+
}

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,41 @@ php-obscene-censor-rus
22
======================
33

44
Класс для фильтрации нецензурных выражений (матов).
5+
6+
Анализ на основе регулярных выражений с списком исключений, совместим с UTF8.
7+
8+
Использование:
9+
10+
```php
11+
$text = 'Да пошел ты нахуй и в пиzdu huesos, ушлепок ебаный, ебать мой вялый хуй!
12+
Мой дед ветеран твоего деда педрилу ебал :( Хуячечки';
13+
14+
ObsceneCensorRus::filterText($text);
15+
16+
echo $text;
17+
//Да пошел ты ***** и в ***** ******, ушлепок ******, ***** мой вялый ***!
18+
//Мой дед ветеран твоего деда ******* **** :( ********
19+
```
20+
21+
```php
22+
$text = ObsceneCensorRus::getFiltered($text);
23+
```
24+
25+
```php
26+
var_dump(ObsceneCensorRus::isAllowed($text));
27+
// false
28+
```
29+
30+
Вторым параметром можно указать кодировку если она отличается от UTF8
31+
```php
32+
ObsceneCensorRus::getFiltered('кто прочитает тот лол', 'CP1251')
33+
```
34+
35+
36+
Тесты:
37+
```
38+
php phpunit.phar ./tests
39+
```
40+
41+
42+
Цензура, антимат, матерщинные слова, фильтр мата, обсценная лексика, нецензурная брань, треугольные сиськи.

tests/Cp1251Test.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
require_once __DIR__ . '/../ObsceneCensorRus.php';
4+
5+
class Cp1251Test extends PHPUnit_Framework_TestCase {
6+
public function testCp1251() {
7+
$this->assertSame('******', ObsceneCensorRus::getFiltered('ÏèÇäÞê', 'CP1251'));
8+
$this->assertSame('*****', ObsceneCensorRus::getFiltered('ñó÷êà', 'CP1251'));
9+
10+
$this->assertSame('DHIWE ******', ObsceneCensorRus::getFiltered('DHIWE E6AHOE', 'CP1251'));
11+
$this->assertSame('********', ObsceneCensorRus::getFiltered('èáàíóøêà', 'CP1251'));
12+
13+
14+
$this->assertTrue(ObsceneCensorRus::isAllowed('îáû÷íûé òåêñò', 'CP1251'));
15+
}
16+
}

tests/FalsePositiveTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
require_once __DIR__ . '/../ObsceneCensorRus.php';
4+
5+
class FalsePositiveTest extends PHPUnit_Framework_TestCase {
6+
public function testFalsePositive() {
7+
$this->assertSame('феерический *******', ObsceneCensorRus::getFiltered('феерический долбоеб'));
8+
$this->assertSame('12 ноября', ObsceneCensorRus::getFiltered('12 ноября'));
9+
}
10+
}

tests/FilterTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
require_once __DIR__ . '/../ObsceneCensorRus.php';
4+
5+
class CensorTest extends PHPUnit_Framework_TestCase
6+
{
7+
public function testCensor()
8+
{
9+
$test = 'Да пошел ты нахуй и в пиzdu huesos, ушлепок ебаный, ебать мой вялый хуй!
10+
Мой дед ветеран твоего деда педрилу ебал :( Хуячечки';
11+
12+
$expected = 'Да пошел ты ***** и в ***** ******, ушлепок ******, ***** мой вялый ***!
13+
Мой дед ветеран твоего деда ******* **** :( ********';
14+
15+
$this->assertSame($expected, ObsceneCensorRus::getFiltered($test));
16+
}
17+
18+
19+
public function testText() {
20+
$test = 'Да пошел ты нахуй и в пиzdu huesos, ушлепок ебаный, ебать мой вялый хуй!
21+
Мой дед ветеран твоего деда педрилу ебал :( Хуячечки';
22+
ObsceneCensorRus::filterText($test);
23+
24+
$this->assertSame('Да пошел ты ***** и в ***** ******, ушлепок ******, ***** мой вялый ***!
25+
Мой дед ветеран твоего деда ******* **** :( ********', $test);
26+
}
27+
28+
29+
public function testLog() {
30+
ObsceneCensorRus::$log = array();
31+
ObsceneCensorRus::$logEx = array();
32+
33+
ObsceneCensorRus::getFiltered('ебанушка');
34+
ObsceneCensorRus::getFiltered('йоба');
35+
ObsceneCensorRus::getFiltered('педик');
36+
ObsceneCensorRus::getFiltered('транквилизатор');
37+
ObsceneCensorRus::getFiltered('Йебать');
38+
ObsceneCensorRus::getFiltered('3 рубля');
39+
ObsceneCensorRus::getFiltered('дайте хлеба в ноябре');
40+
41+
42+
$this->assertSame(array(
43+
'ебанушка' => 1,
44+
'йоба' => 1,
45+
'педик' => 1,
46+
'Йебать' => 1,
47+
),
48+
ObsceneCensorRus::$log);
49+
50+
51+
$this->assertSame(array(
52+
'рубля' => 1,
53+
'ноябре' => 1,
54+
),
55+
ObsceneCensorRus::$logEx);
56+
57+
58+
ObsceneCensorRus::$log = null;
59+
ObsceneCensorRus::$logEx = null;
60+
}
61+
62+
63+
64+
public function testAllowed() {
65+
$this->assertTrue(ObsceneCensorRus::isAllowed('Ан нет. Готовит снова рок Последний жесткий свой урок.'));
66+
$this->assertFalse(ObsceneCensorRus::isAllowed('Итак, пиздец приходит дяде. Навек прощайте, водка, бляди…'));
67+
}
68+
69+
70+
71+
}

0 commit comments

Comments
 (0)