====== Пользовательский ввод ======
===== QValidator =====
Является базовым, абстрактным классом для проверки ввода.\\
Принято **3 состояния** проверки: **Acceptable/Invalid** и **Intermediate**- промежуточное (редактируемое) состояние, т.е. в данном виде строка не корректна, но она может стать таковой.\\
Данный класс может использоваться как **с виджетами** типа **QLineEdit**, **QSpinEdit** или **QComboBox**, так же **и самостоятельно**, с функцией для проверки- **validate()**.\\
Функция **fixup()** может помочь **исправить** некоторые пользовательские ошибки (по умолчанию ничего не делает).\\
Есть возможность локализовать ввод под языковой стандарт- **setLocale()**.\\
Так же есть сигнал **changet()**.\\
==== QDoubleValidator ====
-----
Обеспечивает верхнюю и нижнюю границы допустимых значений, а так же кол-во символов в десятичной части. **fixup()** отсутствует.\\
Присутствует указание нотации, **setNotation()**: стандартная и научная нотации.\\
==== QIntValidator ====
-----
Во многом аналогично предыдущему, проверка ввода чисел, задание диапазона и т.д.\\
==== QRegExpValidator / QRegularExpresionValidator ====
-----
Используется регулярное выражение, для проверки строки.\\
Совпадение проверяется со всей входной строкой, от начала до конца. Если введенная строка является префиксом целевой (не полной) то она считается промежуточной, с соответствующим статусом (**Intermediate**).\\
===== QRegExp / QRegularExpression =====
-----
**QRegularExpression** является улучшением класса **QRegExp**, добавлен с пятой версии Qt, и рекомендуется к использованию, далее **описание касается именно его**.\\
Реализует Perl-совместимые регулярные выражения.\\
Выражение состоит из двух частей: **строки шаблона** и **набора параметров шаблона**.\\
**Параметры шаблона** задаются отдельно, в конструкторе либо функцией **setPatternOptions()**. Позволяют установить пар-ры типа учета регистра и т.д. (enum QRegularExpression :: PatternOption).\\
**Тип соответствия**- есть возможность задать тип соответствия (обычный либо частичный). Так же есть еще параметры соответствия (**QRegularExpression :: MatchOption**), но там хз, хня какая то.\\
==== Соответствие ====
-----
Выполнить сопоставление можно методом **match()**, передав предметную строку, результатом является объект **QRegularExpressionMatch**.\\
При успешной проверке можно выполнить извлечение найденных **подстрок**, метод **captured()** (0== вся подстрока) (смещение для начала поиска так же работает (match())).\\
:!: Пример: Поиск и извлечение подстроки
/*...*/
QRegularExpression vReg("\\d\\d \\w+");
QRegularExpressionMatch vMatch= vReg.match("abc123 def");
if(vMatch.hasMatch())
QString vFinded= vMatch.captured(0);
/*...*/
// Еще пример
QRegularExpression vReg("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$");
QRegularExpressionMatch vMatch= vReg.match("08/12/1985");
if(vMatch.hasMatch())
{
QString vDay= vMatch.captured(1); // == 08
QString vMon= vMatch.captured(2); // == 12
QString vYear= vMatch.captured(3); // == 1985
}
/*...*/
// Либо именованные части
QRegularExpression vReg("^(?\\d\\d)/(?\\d\\d)/(?\\d\\d\\d\\d)$");
QRegularExpressionMatch vMatch= vReg.match("08/12/1985");
if(vMatch.hasMatch())
{
QString vDay= vMatch.captured("day"); // == 08
QString vMon= vMatch.captured("month"); // == 12
QString vYear= vMatch.captured("year"); // == 1985
}
==== Глобальное соответствие ====
-----
Поиск всех вхождений выражения в строке. Метод **globalMatch()** возвращает **QRegularExpressionMatchIterator**- т.н. прямой итератор который можно использовать для перебора результатов.\\
Результат возвращается как объект **QRegularExpressionMatch**.\\
:!: Пример: Глобальный поиск и список результатов
QRegularExpression vReg("(\\w+)");
QRegularExpressionMatchIterator i= vReg.globalMatch("the quick fox");
QStringList vLsWords;
while(i.hasNext())
{
QRegularExpressionMatch vMatch= i.next();
QString vWord= vMatch.captured(1);
vLsWords << vWord;
}
==== Частичное соответствие ====
-----
Совпадение части строки, алгоритм менее эффективный т.к. многие оптимизации не применяются.\\
Частичный поиск явно запрашивается, указав соответствующий тип в **match()**/**globalmatch()**.\\
Для получения используется метод **hasPartialMatch()** т.к. **hasMatch()** вернет false, но запрос частичного совпадения все равно может найти полное совпадение, тогда **hasMatch()== true** а **hasPartialMatch()== false**. Объект никогда не сообщает о том и о другом соответствии.\\
Подстроки (**captured()**) так же не возвращаются, только полная.\\
:!: Пример: Предпочтение полного сопоставления частичному
/*...*/
QRegularExpression vReg("abc\\w+X|def");
QRegularExpressionMatch vMatch= vReg.match("abcdef", 0, QRegularExpression::PartialPreferCompleteMatch);
vMatch.hasMatch(); // == true
vMatch.hasPartialMatch(); // == false
vMatch.captured(0); // == "def" т.к. это полное соответствие и оно в приоритете
/*...*/
**Инкрементальное/сегментное соответствие**- в случае если проверочный текст подается порциями, тогда логика проверки учитывает возможное продолжение текста, что собсна влияет на результат.\\
Используется флаг **QRegularExpression::PartialPreferFirstMatch**.\\
==== Синтаксические ошибки ====
-----
Синтаксические ошибки шаблона можно проверить методом **isValid()**, до информацию **errorString()**, так же, смещение **patternErrorOffset()**.\\
:!: Пример: