Init
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package ru.pdguard.detect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Одно правило детекции персональных данных.
|
||||
*
|
||||
* <p>Добавление нового типа ПД — это добавление одного {@code Rule} в
|
||||
* {@link RuleRegistry}; менять остальной код не требуется.
|
||||
*
|
||||
* @param type тип ПД, который распознаёт правило
|
||||
* @param pattern регулярное выражение
|
||||
* @param priority приоритет при разрешении перекрытий
|
||||
* @param groups номера групп, которые маскируются; {@code 0} — всё совпадение целиком.
|
||||
* Несколько групп нужны, когда значение разорвано словами:
|
||||
* «серия 4509 номер 123456»
|
||||
* @param validator дополнительная проверка значения (контрольная сумма, диапазон дат);
|
||||
* {@code null} — проверка не нужна
|
||||
* @param veto шаблон окружения, при котором совпадение персональными данными не считается:
|
||||
* адрес отделения банка не является ПД, хотя выглядит как адрес
|
||||
* @param context шаблон окружения, который обязан присутствовать рядом. Нужен там,
|
||||
* где форма совпадения сама по себе слишком общая: «Невский проспект»
|
||||
* это адрес рядом с домом и индексом и просто топоним в рассказе о городе
|
||||
* @param anchors строчные подстроки, одна из которых обязана встретиться в тексте.
|
||||
* Проверка через {@code indexOf} на порядок дешевле запуска
|
||||
* регулярного выражения и отсекает большинство правил на коротком
|
||||
* запросе. Пустой список — правило запускается всегда
|
||||
*/
|
||||
public record Rule(String type, Pattern pattern, int priority, List<Integer> groups,
|
||||
Predicate<String> validator, Pattern veto, Pattern context, List<String> anchors) {
|
||||
|
||||
/**
|
||||
* Флаги компиляции для всех правил.
|
||||
*
|
||||
* <p>{@code UNICODE_CHARACTER_CLASS} обязателен: без него {@code \w}, {@code \W}
|
||||
* и {@code \b} в Java охватывают только латиницу, и якорные слова вроде
|
||||
* «водительское удостоверение» не находятся. {@code UNICODE_CASE} делает
|
||||
* {@code (?i)} корректным для кириллицы.
|
||||
*/
|
||||
private static final int FLAGS = Pattern.UNICODE_CHARACTER_CLASS | Pattern.UNICODE_CASE;
|
||||
|
||||
/** Сколько символов слева и справа от совпадения просматривает вето-шаблон. */
|
||||
public static final int VETO_LOOKBEHIND = 80;
|
||||
public static final int VETO_LOOKAHEAD = 40;
|
||||
|
||||
/** Правило без проверок, маскируется всё совпадение. */
|
||||
public static Rule of(String type, String regex, int priority) {
|
||||
return new Rule(type, Pattern.compile(regex, FLAGS), priority, List.of(0), null, null, null, List.of());
|
||||
}
|
||||
|
||||
/** Маскировать только перечисленные группы, а не всё совпадение. */
|
||||
public Rule groups(Integer... indexes) {
|
||||
return new Rule(type, pattern, priority, List.of(indexes), validator, veto, context, anchors);
|
||||
}
|
||||
|
||||
/** Принять совпадение, только если значение прошло проверку. */
|
||||
public Rule validatedBy(Predicate<String> check) {
|
||||
return new Rule(type, pattern, priority, groups, check, veto, context, anchors);
|
||||
}
|
||||
|
||||
/** Запускать правило, только если в тексте есть одна из подстрок (в нижнем регистре). */
|
||||
public Rule anchoredBy(String... required) {
|
||||
return new Rule(type, pattern, priority, groups, validator, veto, context, List.of(required));
|
||||
}
|
||||
|
||||
/** Есть ли в тексте хоть один из якорей правила. */
|
||||
public boolean mayMatch(String lowercasedText) {
|
||||
if (anchors.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (String anchor : anchors) {
|
||||
if (lowercasedText.contains(anchor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Принять совпадение, только если рядом встретилось указанное слово. */
|
||||
public Rule requiringNear(String regex) {
|
||||
return new Rule(type, pattern, priority, groups, validator, veto, Pattern.compile(regex, FLAGS), anchors);
|
||||
}
|
||||
|
||||
/** Отбросить совпадение, если рядом встретилось указанное слово. */
|
||||
public Rule vetoedBy(String regex) {
|
||||
return new Rule(type, pattern, priority, groups, validator, Pattern.compile(regex, FLAGS), context, anchors);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user