Регулярное выражение работает на regex101.com, но не в коде программы

Есть следующий QRegExp: QRegExp numberRegExp("^(7|8){1}\d{8,10}$");

  • для проверки телефонного номера в формате +7********** или +8********** (без знака + - указан, чисто для примера), выражение проверенно на https://regex101.com/ - в формате PCRE, однако, при проверке: numberRegExp.exactMatch("some number") - возвращает false.

Уточню, что в строке - только цифры,ничего лишнего и на вышеуказанном сайте - происходит полное совпадение , т.е, согласно документации - exactMatch - должен вернуть true.

Примеры валидных номеров:

71234567891,

81234567891,

7123456789,

8123456789,

712345678,

812345678

  • т.е,префикс состоящий из одной цифры - 7 или 8 и от 8 до 10 цифр, идущих после префикса.

p.s - не смог придумать более подходящего заголовка, буду признателе, за предложенные правки и более подходящие варианты.Спасибо.


Ответы (1 шт):

Автор решения: Wiktor Stribiżew

Удвойте символы обратной косой черты:

QRegExp numberRegExp("^(7|8)\\d{8,10}$");
QRegExp numberRegExp(R"(^(7|8)\d{8,10}$)");

Проблема в том, что ваш строковой литерал содержит текст ^(7|8)d{8,10}$, где \ отсутствует по причине того, что не существует строковой управляющей последовательности \d, и ядро C++ удаляет символы обратной косой черты из таких неверных упраляющих последовательностей.

Всегда удаляйте из регулярных выражений {1}, так как любой неквантифицируемый символ/шаблон находится один раз по умолчанию.

Подробности

Запомните: регулярыне выражения — это буквальный текст. Текст можно по-разному задать в коде программы, например, чтение из файла, присвоение значения с помощью строковой константы/литерала.

В вашем коде используется "обычный строковой литерал". Такие строковые литералы поддерживают строковые управляющие последовательности (string escape sequences). Например, текст 2+"2" в тексте программы можно задать с помощью обычного строкового литерала "2+\"2\"" с двойными кавычками в качестве разделителей. А ещё можно его задать в виде "2\x2B\x222\x22".

В обычных строковых литералах символ обратной косой черты является "специальным", и чтобы задать в строке сам буквальный символ \, нужно его самого "экранировать", т.е. по сути его нужно удвоить. Именно буквальный символ обратной косой черты является первым символом управляющих последовательностей регулярных выражений. Управляющие последовательности регулярных выражений (regex escape sequences) — это всем известные \d, \w, \s, \D, \W, \S, \b, \B, \\, \uXXXX, \xNN, \+, \$, \) и так далее.

В C++ и во многих других языках есть возможность задать текстовую переменную с помощью строковых литералах, в которых поддержка строковых управляющих последовательностей отсутствует. Это так называемые "сырые" строковые литералы, "raw string literals" ("verbatim string literals" в C# и т.д.). В C++ можно задать такой литрал с помощью префикса R. Строковой литерал R"(\d{3})" (равный "\\d{3}") хранит в себе текст \d{3}, то есть шаблон регулярных выражений для поиска трёх последовательных цифр. Обратите внимание: круглые скобки — это разделители, функциональная часть строкового литерала, они вовсе не задают дополнительной захватывающей подмаски в регулярном выражении.

→ Ссылка