база данных — Существует ли массив… матов?
Вопрос задан
Изменён 5 лет 2 месяца назад
Просмотрен 14k раз
Пишу авторизацию в приложении и хочется отсечь попытки неадекватных школьников уже на этом этапе вписать в EditText
невалидное имя (маты).
Проверку хотел сделать через .contains
ArrayList<String>
, дак вот после наверное двадцатого элемента фантазия кончилась 🙂 да и не совсем по душе пришлось занятие 🙂
Поэтому вопрос — может кто уже делал подобную БД и может поделиться (на полный список не рассчитываю по понятным причинам), чтобы просто Ctrl+C, Ctrl+V.
PS. Просьба отнестись с пониманием и не пинать больно — с подобной задачей столкнулся впервые.
- база-данных
9
Тема стара как мир.
Из того, что я видел, именно php-censure — скрипт на PHP для определения нецензурных слов — оказался лучше других по отзывам. Можете взять на вооружение подход, который в нём используется: «плохие» слова определяются по частям. Отдельно приставка, отдельно корень и тд. Именно потому, что матерных слов существует не много, а много — производных от них, такой подход работает хорошо. Также используется список «хороших» слов, чтобы не зацензурировать лишнего.
- А вот на форуме Vingrad выложили архив из ~200 матерных выражений (нужна учётная запись на сайте для скачивания).
- Список, используемый в zlo-search.
- Список нецензурных слов и производных.
- Список нецензурных слов для анти-спама и цензуры.
Зарегистрируйтесь или войдите
Регистрация через GoogleРегистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
Фильтр нецензурной лексики за 5 минут / Хабр
Привет, Хабр.
Для одного из моих проектов мне понадобилось сделать фильтр мата. Сегодня мы попытаемся сделать его за несколько минут. Ну что же, приступим.
Анализирование
#Фраза, которую будем проверять. phrase = input("Введите фразу для проверки: ") #Искомое слово. Пока что только одно. words = ["банан"] #Фрагменты, которые получатся после разбиения слова. fragments = [] #Проходимся по всем словам. for word in words: #Разбиваем слово на части, и проходимся по ним. for part in range(len(phrase)): #Вот сам наш фрагмент. fragment = phrase[part: part+len(word)] #Сохраняем его в наш список. fragments.append(fragment) #Выводим получившиеся фрагменты. print(fragments)Запускаем наш файл и вводим фразу.
Введите фразу для проверки: Привет, я банан. ['Приве', 'ривет', 'ивет,', 'вет, ', 'ет, я', 'т, я ', ', я б', ' я ба', 'я бан', ' бана', 'банан', 'анан.', 'нан.', 'ан.', 'н.', '.']
Вот что у нас получилось. Смотрим на все фрагменты и видим среди них искомое слово «банан». Теперь нам осталось сравнить эти фрагменты с искомыми словами.
Сравнение
Для того, чтобы сравнивать фрагменты с искомыми словами, я решил просто использовать цикл.
#Проходимся по всем словам. for word in words: #Проходимся по всем фрагментам. for fragment in fragments: #Сравниваем фрагмент и искомое слово if word == fragment: #Если они равны, выводим надпись о их нахождении. print("Найдено", word)
Смотрим.
Введите фразу для проверки: Привет, я банан.['Приве', 'ривет', 'ивет,', 'вет, ', 'ет, я', 'т, я ', ', я б', ' я ба', 'я бан', ' бана', 'банан', 'анан.', 'нан.', 'ан.', 'н.', '.'] Найдено банан
Все, простейший фильтр нецензурной лексики готов!
Доработки
Простейший фильтр был готов, но я решил его чуточку дополнить.
Так как русский человек очень изобретателен, то он может поменять некоторые буквы на другой язык. Например, «бaнaн». Здесь место обычной «а», я поставил английскую. И теперь наш фильтр не будет распознавать это слово.
Введите фразу для проверки: Привет, я бaнaн. ['Приве', 'ривет', 'ивет,', 'вет, ', 'ет, я', 'т, я ', ', я б', ' я бa', 'я бaн', ' бaнa', 'бaнaн', 'aнaн.', 'нaн.', 'aн.', 'н.', '.']
Фильтр не вывел ничего, а значит не нашел слово. Поэтому мы должны создать дополнительный фильтр, который будет переводить буквы английского алфавита и похожие символы в русский текст.
В интернете я нашел вот такой список, который чуточку доработал.
d = {'а' : ['а', 'a', '@'], 'б' : ['б', '6', 'b'], 'в' : ['в', 'b', 'v'], 'г' : ['г', 'r', 'g'], 'д' : ['д', 'd', 'g'], 'е' : ['е', 'e'], 'ё' : ['ё', 'e'], 'ж' : ['ж', 'zh', '*'], 'з' : ['з', '3', 'z'], 'и' : ['и', 'u', 'i'], 'й' : ['й', 'u', 'i'], 'к' : ['к', 'k', 'i{', '|{'], 'л' : ['л', 'l', 'ji'], 'м' : ['м', 'm'], 'н' : ['н', 'h', 'n'], 'о' : ['о', 'o', '0'], 'п' : ['п', 'n', 'p'], 'р' : ['р', 'r', 'p'], 'с' : ['с', 'c', 's'], 'т' : ['т', 'm', 't'], 'у' : ['у', 'y', 'u'], 'ф' : ['ф', 'f'], 'х' : ['х', 'x', 'h' , '}{'], 'ц' : ['ц', 'c', 'u,'], 'ч' : ['ч', 'ch'], 'ш' : ['ш', 'sh'], 'щ' : ['щ', 'sch'], 'ь' : ['ь', 'b'], 'ы' : ['ы', 'bi'], 'ъ' : ['ъ'], 'э' : ['э', 'e'], 'ю' : ['ю', 'io'], 'я' : ['я', 'ya'] }
Перед фильтрацией мы должны перевести весь текст в нижний регистр и убрать все пробелы, так как кто-нибудь может ввести искомые слова вот так: «БАНАН» или «б а н а н».
phrase = phrase.lower().replace(" ", "")
Теперь мы должны как-то сравнить этот список с нашим текстом. Для этого я создал вот такую функцию.
#Проходимся по нашему словарю. for key, value in d.items(): #Проходимся по каждой букве в значении словаря. То есть по вот этим спискам ['а', 'a', '@']. for letter in value: #Проходимся по каждой букве в нашей фразе. for phr in phrase: #Если буква совпадает с буквой в нашем списке. if letter == phr: #Заменяем эту букву на ключ словаря. phrase = phrase.replace(phr, key)
Что у нас получилось теперь.
Введите фразу для проверки: Привет, я б@н@н. ['Приве', 'ривет', 'ивет,', 'вет, ', 'ет, я', 'т, я ', ', я б', ' я ба', 'я бан', ' бана', 'банан', 'анан.', 'нан.', 'ан.', 'н.', '.'] Найдено банан
То, что у нас не находилось раньше теперь легко распознаётся.
Расстояние Левенштейна
Я понял, что если хоть чуточку изменить слово, то его уже невозможно найти.
Введите фразу для проверки: Я люблю бонан. ['Я люб', ' любл', 'люблю', 'юблю ', 'блю б', 'лю бо', 'ю бон', ' бона', 'бонан', 'онан.', 'нан.', 'ан.', 'н.', '.']
Наши опасения подтвердились, но решения этой проблемы есть расстояние Левенштейна.
В интернете я нашел функцию этого алгоритма для python. Вот как она выглядит.
def distance(a, b): "Calculates the Levenshtein distance between a and b." n, m = len(a), len(b) if n > m: # Make sure n <= m, to use O(min(n, m)) space a, b = b, a n, m = m, n current_row = range(n + 1) # Keep current and previous row, not entire matrix for i in range(1, m + 1): previous_row, current_row = current_row, [i] + [0] * n for j in range(1, n + 1): add, delete, change = previous_row[j] + 1, current_row[j - 1] + 1, previous_row[j - 1] if a[j - 1] != b[i - 1]: change += 1 current_row[j] = min(add, delete, change) return current_row[n]
Теперь мы должны переписать функцию сравнения.
#Проходимся по всем словам. for word in words: #Проходимся по всем фрагментам. for fragment in fragments: #Если отличие этого фрагмента меньше или равно 25% этого слова, то считаем, что они равны. if distance(fragment, word) <= len(word)*0.25: #Если они равны, выводим надпись о их нахождении. print("Найдено", word)
Что у нас получилось теперь.
Введите фразу для проверки: Я люблю бонан. ['Я люб', ' любл', 'люблю', 'юблю ', 'блю б', 'лю бо', 'ю бон', ' бона', 'бонан', 'онан.', 'нан.', 'ан.', 'н.', '.'] Найдено банан
Небольшие проблемы
Наверное вы уже догадались, что если в списке для фильтрации будет больше одного слова, то он будет некорректно работать. Поэтому я переписал это всё в один цикл.
#Проходимся по всем словам. for word in words: #Разбиваем слово на части, и проходимся по ним. for part in range(len(phrase)): #Вот сам наш фрагмент.fragment = phrase[part: part+len(word)] #Если отличие этого фрагмента меньше или равно 25% этого слова, то считаем, что они равны. if distance(fragment, word) <= len(word)*0.25: #Если они равны, выводим надпись о их нахождении. print("Найдено", word, "\nПохоже на", fragment)
Все, наш фильтр полностью готов.
Код фильтра
import string words = ["банан", "помидор"] print("Фильтруемые слова:", words) #Фраза, которую будем проверять. phrase = input("Введите фразу для проверки: ").lower().replace(" ", "") def distance(a, b): "Calculates the Levenshtein distance between a and b." n, m = len(a), len(b) if n > m: # Make sure n <= m, to use O(min(n, m)) space a, b = b, a n, m = m, n current_row = range(n + 1) # Keep current and previous row, not entire matrix for i in range(1, m + 1): previous_row, current_row = current_row, [i] + [0] * n for j in range(1, n + 1): add, delete, change = previous_row[j] + 1, current_row[j - 1] + 1, previous_row[j - 1] if a[j - 1] != b[i - 1]: change += 1 current_row[j] = min(add, delete, change) return current_row[n] d = {'а' : ['а', 'a', '@'], 'б' : ['б', '6', 'b'], 'в' : ['в', 'b', 'v'], 'г' : ['г', 'r', 'g'], 'д' : ['д', 'd'], 'е' : ['е', 'e'], 'ё' : ['ё', 'e'], 'ж' : ['ж', 'zh', '*'], 'з' : ['з', '3', 'z'], 'и' : ['и', 'u', 'i'], 'й' : ['й', 'u', 'i'], 'к' : ['к', 'k', 'i{', '|{'], 'л' : ['л', 'l', 'ji'], 'м' : ['м', 'm'], 'н' : ['н', 'h', 'n'], 'о' : ['о', 'o', '0'], 'п' : ['п', 'n', 'p'], 'р' : ['р', 'r', 'p'], 'с' : ['с', 'c', 's'], 'т' : ['т', 'm', 't'], 'у' : ['у', 'y', 'u'], 'ф' : ['ф', 'f'], 'х' : ['х', 'x', 'h' , '}{'], 'ц' : ['ц', 'c', 'u,'], 'ч' : ['ч', 'ch'], 'ш' : ['ш', 'sh'], 'щ' : ['щ', 'sch'], 'ь' : ['ь', 'b'], 'ы' : ['ы', 'bi'], 'ъ' : ['ъ'], 'э' : ['э', 'e'], 'ю' : ['ю', 'io'], 'я' : ['я', 'ya'] } for key, value in d. items(): #Проходимся по каждой букве в значении словаря. То есть по вот этим спискам ['а', 'a', '@']. for letter in value: #Проходимся по каждой букве в нашей фразе. for phr in phrase: #Если буква совпадает с буквой в нашем списке. if letter == phr: #Заменяем эту букву на ключ словаря. phrase = phrase.replace(phr, key) #Проходимся по всем словам. for word in words: #Разбиваем слово на части, и проходимся по ним. for part in range(len(phrase)): #Вот сам наш фрагмент. fragment = phrase[part: part+len(word)] #Если отличие этого фрагмента меньше или равно 25% этого слова, то считаем, что они равны. if distance(fragment, word) <= len(word)*0.25: #Если они равны, выводим надпись о их нахождении. print("Найдено", word, "\nПохоже на", fragment)
Список выбора ковриков Angular не работает должным образом с вводом поиска
спросил
Изменено 4 года, 9 месяцев назад
Просмотрено 3к раз
Работа над проектом angular5, где я использую список выбора материалов angular, который не работает должным образом с поиском входного текста вверху.
Вот код на stackblitz. https://stackblitz.com/edit/angular-i3pfu2-xgembc
Шаги:
- Выберите из списка «Кроссовки» и «Мокасины»
- Поиск с текстом «clo»
- Удалить текст из поля ввода.
- См. список выбора, ранее выбранная опция автоматически отменяет выбор, чего не должно происходить.
Как мы можем сохранить ранее выбранную опцию в списке? Заранее спасибо.
- угловой
- угловой материал2
4
Вы можете просто расширить свой массив строк typesOfShoes, чтобы он был массивом объектов с выбранным свойством, и самостоятельно обрабатывать логику.
typesOfShoes = [{имя:'Ботинки',выбрано:ложь}, {имя:'Сабо',выбрано:ложь}, {имя:'Мокасины',выбрано:ложь}, {имя:'Мокасины',выбрано: false}, {name:'Кроссовки', selected:false}];
Я не знаю, как работает компонент списка выбора материалов, но я уверен, что вы знаете, как использовать директиву (click) для смены обуви. выбрано: (shoe.selected = !show.selected)
редактировать
Для полноты:
{{обувь.имя}} мат-выбор-список>
1
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
фильтр выбора мата — npm
Github
https://github. com/mdlivingston/mat-select-filter
Описание
Фильтр выбора мата — это фильтр для раскрывающихся списков выбора материала. В настоящее время они не поддерживают это, поэтому я решил сделать свой собственный.
Демонстрация
Установить
npm
$ npm установить мат-выбор фильтра
Как использовать
Обязательно импортируйте в нужный модуль:
import { MatSelectFilterModule } из 'mat-select-filter';
Далее просто добавляем его в нужный материал select:
<мат-выбор> {{переменная}} мат-выбрать>
Отправьте нужный отфильтрованный массив, используя [array]=»variables» или [array]=»[‘one’, ‘two’, ‘three’]». Теперь он принимает объекты массива благодаря Sen Alexandru. Чтобы использовать массив объектов, просто укажите значение ключа объектов, которое вы хотите отфильтровать, используя ввод [displayMember]. Например:
переменные переменные = [ { идентификатор: 0, имя: 'тест1' }, { идентификатор: 0, имя: 'тест1' } ]
<мат-форм-поле> <мат-выбор>{{переменная}} мат-выбрать>
mat-select-filter теперь поддерживает поддержку групп опций благодаря jenniferarce! Просто введите логическое значение [hasGroup] в true и добавьте строку [groupArrayName]!
Метод (filteredReturn) возвращает отфильтрованные результаты после каждого действия с клавиатурой во время поиска…
[noResultsMessage] — это строка, которую вы хотели бы отобразить, если вы не фильтруете результаты.
[showSpinner] позволяет вам отключить отображение счетчика загрузки во время фильтрации.
Доступ к тексту-заполнителю для окна поиска осуществляется с помощью:
, но по умолчанию это «Поиск…»
Чтобы сфокусировать поисковый ввод на каждом щелчке, вы можете сделать что-то вроде этого:
{{переменная}} мат-выбрать>
, иначе он сфокусируется только один раз.
Чтобы добавить цветной фон, сделайте что-то вроде этого:
Вы также можете изменить классы из глобального файла css/scss в своем проекте, добавив:
.