Класс QRegExp
Класс QRegExp предоставляет сопоставление шаблонов с использованием регулярных выражений. Подробнее...
| Заголовок: | #include <QRegExp> |
| qmake: | QT += core |
Примечание: Все функции в этом классе являются реентерабельными.
Типы
| Перечисление | CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch } |
| Перечисление | PatternSyntax { RegExp, RegExp2, Wildcard, WildcardUnix, FixedString, W3CXmlSchema11 } |
Открытые функции
| QRegExp(const QRegExp &rx) | |
| QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive, QRegExp::PatternSyntax syntax = RegExp) | |
| QRegExp() | |
| QRegExp & | operator=(QRegExp &&other) |
| QRegExp & | operator=(const QRegExp &rx) |
| ~QRegExp() | |
| QString | cap(int nth = 0) const |
| int | captureCount() const |
| QStringList | capturedTexts() const |
| Qt::CaseSensitivity | caseSensitivity() const |
| QString | errorString() const |
| bool | exactMatch(const QString &str) const |
| int | indexIn(const QString &str, int offset = 0, QRegExp::CaretMode caretMode = CaretAtZero) const |
| bool | isEmpty() const |
| bool | isMinimal() const |
| bool | isValid() const |
| int | lastIndexIn(const QString &str, int offset = -1, QRegExp::CaretMode caretMode = CaretAtZero) const |
| int | matchedLength() const |
| QString | pattern() const |
| QRegExp::PatternSyntax | patternSyntax() const |
| int | pos(int nth = 0) const |
| void | setCaseSensitivity(Qt::CaseSensitivity cs) |
| void | setMinimal(bool minimal) |
| void | setPattern(const QString &pattern) |
| void | setPatternSyntax(QRegExp::PatternSyntax syntax) |
| void | swap(QRegExp &other) |
| bool | operator!=(const QRegExp &rx) const |
| bool | operator==(const QRegExp &rx) const |
Статические открытые члены
| QString | escape(const QString &str) |
Связанные нечлены
| uint | qHash(const QRegExp &key, uint seed = 0) |
| QDataStream & | operator<<(QDataStream &out, const QRegExp ®Exp) |
| QDataStream & | operator>>(QDataStream &in, QRegExp ®Exp) |
Подробное описание
Регулярное выражение (или "regexp") — это шаблон для сопоставления подстрок в тексте. Это полезно во многих контекстах, например:
| Валидация | Regexp может проверить, соответствует ли подстрока некоторым критериям, например, является ли она целым числом или не содержит пробелов. |
| Поиск | Regexp обеспечивает более мощное сопоставление шаблонов, чем простое сопоставление подстрок, например, найти одно из слов mail, letter или correspondence, но не email, mailman, mailer, letterbox и т. д. |
| Поиск и замена | Regexp может заменить все вхождения подстроки на другую подстроку, например, заменить все вхождения & на & за исключением случаев, когда & уже последует amp;. |
| Разбиение строк | Regexp может использоваться для определения места, где строка должна быть разделена, например, для разделения табулированных строк. |
Представлено краткое введение в regexp, описание языка regexp Qt, некоторые примеры и сама документация функций. QRegExp моделируется по языку regexp Perl. Он полностью поддерживает Unicode. QRegExp также может использоваться в более простом режиме «шаблонов», аналогичном функциональности, встречающейся в командных оболочках. Правила синтаксиса, используемые QRegExp, могут быть изменены с помощью setPatternSyntax(). В частности, синтаксис шаблона может быть установлен в QRegExp::FixedString, что означает, что шаблон для сопоставления интерпретируется как обычная строка, т. е. специальные символы (например, обратный слэш) не экранируются.
Хорошая книга о regexp — Mastering Regular Expressions (Третье издание) Джеффри Э. Ф. Фридла, ISBN 0-596-52812-4.
Примечание: В Qt 5 новый класс QRegularExpression предоставляет совместимую с Perl реализацию регулярных выражений и рекомендуется вместо QRegExp.
Введение
Regexp строятся из выражений, квантификаторов и утверждений. Самое простое выражение — это символ, например, x или 5. Выражение также может представлять собой набор символов, заключенных в квадратные скобки. [ABCD] будет соответствовать A или B или C или D. Мы можем записать это же выражение как [A-D], а выражение для сопоставления любой заглавной буквы английского алфавита записывается как [A-Z].
Квантификатор указывает количество вхождений выражения, которые должны быть сопоставлены. x{1,1} означает сопоставление ровно одного x. x{1,5} означает сопоставление последовательности символов x, которая содержит по крайней мере один x, но не более пяти.
Обратите внимание, что в общем случае regexp нельзя использовать для проверки сбалансированных скобок или тегов. Например, regexp можно записать для сопоставления открывающего html <b> и его закрывающего </b>, если <b> теги не вложены, но если <b> теги вложены, тот же regexp будет сопоставлять открывающий <b> тег с неправильным закрывающим </b>. Для фрагмента <b>bold <b>bolder</b></b>, первый <b> будет сопоставлен с первым </b>, что неверно. Однако можно записать regexp, который будет корректно сопоставлять вложенные скобки или теги, но только если количество уровней вложенности фиксировано и известно. Если количество уровней вложенности не фиксировано и неизвестно, нельзя записать regexp, который не потерпит неудачи.
Предположим, нам нужен регулярное выражение для поиска целых чисел в диапазоне от 0 до 99. Требуется хотя бы одна цифра, поэтому мы начинаем с выражения [0-9]{1,1}, которое соответствует одной цифре ровно один раз. Это регулярное выражение соответствует целым числам в диапазоне от 0 до 9. Для поиска целых чисел до 99, увеличьте максимальное количество вхождений до 2, так что регулярное выражение становится [0-9]{1,2}. Это регулярное выражение удовлетворяет исходному требованию по поиску целых чисел от 0 до 99, но оно также будет соответствовать целым числам, которые встречаются посреди строк. Если мы хотим, чтобы найденное целое число было всей строкой, мы должны использовать утверждения якорей, ^ (крышка) и $ (доллар). Когда ^ — это первый символ в регулярном выражении, это означает, что регулярное выражение должно соответствовать началу строки. Когда $ — это последний символ регулярного выражения, это означает, что регулярное выражение должно соответствовать концу строки. Регулярное выражение становится ^[0-9]{1,2}$. Обратите внимание, что утверждения, например, ^ и $, не соответствуют символам, а позициям в строке.
Если вы видели регулярные выражения, описанные в другом месте, они могли выглядеть иначе, чем показанные здесь. Это потому, что некоторые наборы символов и некоторые квантификаторы настолько распространены, что им присвоены специальные символы для их обозначения. [0-9] можно заменить символом \d. Квантификатор для соответствия ровно одному вхождению, {1,1}, можно заменить самим выражением, т.е. x{1,1} — то же самое, что и x. Таким образом, наш соответчик для чисел от 0 до 99 можно записать как ^\d{1,2}$. Его также можно записать как ^\d\d{0,1}$, т.е. С начала строки найдите цифру, сразу за ней 0 или 1 цифру. На практике это будет записано как ^\d\d?$. Символ ? является сокращением для квантификатора {0,1}, т.е. 0 или 1 вхождений. ? делает выражение необязательным. Регулярное выражение ^\d\d?$ означает С начала строки, найдите одну цифру, сразу за ней 0 или 1 дополнительную цифру, сразу за ней конец строки.
Чтобы написать регулярное выражение, которое соответствует одному из слов 'mail', 'letter' или 'correspondence', но не соответствует словам, содержащим эти слова, например, 'email', 'mailman', 'mailer' и 'letterbox', начните с регулярного выражения, которое соответствует 'mail'. В полном виде регулярное выражение — m{1,1}a{1,1}i{1,1}l{1,1}, но поскольку выражение для символа автоматически квантифицируется с помощью {1,1}, мы можем упростить регулярное выражение до mail, т.е. 'm', за которым следует 'a', за которым следует 'i', за которым следует 'l'. Теперь мы можем использовать вертикальную черту |, которая означает или, чтобы включить другие два слова, так что наше регулярное выражение для поиска любого из трёх слов становится mail|letter|correspondence. Найдите 'mail' или 'letter' или 'correspondence'. Хотя это регулярное выражение будет соответствовать одному из трех слов, которые мы хотим найти, оно также будет соответствовать словам, которые мы не хотим искать, например, 'email'. Чтобы предотвратить соответствие регулярного выражения нежелательным словам, мы должны указать ему начать и закончить соответствие на границах слов. Сначала заключим наше регулярное выражение в скобки, (mail|letter|correspondence). Скобки группируют выражения, и они идентифицируют часть регулярного выражения, которую мы хотим извлечь. Заключение выражения в скобки позволяет использовать его как компонент в более сложных регулярных выражениях. Это также позволяет нам определить, какое из трех слов фактически совпало. Чтобы принудить соответствие к началу и концу на границах слов, мы заключаем регулярное выражение в утверждения границ слов \b: \b(mail|letter|correspondence)\b. Теперь регулярное выражение означает: Найдите границу слова, затем выражение в скобках, затем границу слова. Утверждение \b соответствует позиции в регулярном выражении, а не символу. Граница слова — это любой небуквенный символ, например, пробел, перевод строки или начало или конец строки.
Если мы хотим заменить символы амперсанда на HTML-сущность &, регулярное выражение для поиска просто &. Но это регулярное выражение также будет соответствовать амперсандам, которые уже были преобразованы в HTML-сущности. Мы хотим заменить только амперсанды, за которыми не следует amp;. Для этого нам нужно утверждение негативного предпросмотра, (?!__). Регулярное выражение можно записать как &(?!amp;), т.е. Найдите амперсанд, за которым не следует amp;.
Если мы хотим подсчитать все вхождения 'Eric' и 'Eirik' в строке, два допустимых решения — \b(Eric|Eirik)\b и \bEi?ri[ck]\b. Утверждение границы слова '\b' требуется, чтобы избежать соответствия словам, содержащим имя, например, 'Ericsson'. Обратите внимание, что второе регулярное выражение соответствует большему количеству вариантов написания, чем нам нужно: 'Eric', 'Erik', 'Eiric' и 'Eirik'.
Некоторые из рассмотренных выше примеров реализованы в разделе примеров кода.
Символы и сокращения для наборов символов
| Элемент | Значение |
|---|---|
| c | Символ представляет собой себя, если только он не имеет специального значения в регулярном выражении. Например, c соответствует символу c. |
| \c | Символ, который следует за обратной косой чертой, соответствует символу самому по себе, за исключением указанного ниже. Например, для соответствия буквальному символу крышки в начале строки, напишите \^. |
| \a | Соответствует ASCII звонку (BEL, 0x07). |
| \f | Соответствует ASCII подаче формы (FF, 0x0C). |
| \n | Соответствует ASCII переводу строки (LF, 0x0A, перевод строки в Unix). |
| \r | Соответствует ASCII возврату каретки (CR, 0x0D). |
| \t | Соответствует ASCII горизонтальной табуляции (HT, 0x09). |
| \v | Соответствует ASCII вертикальной табуляции (VT, 0x0B). |
| \xhhhh | Соответствует Unicode-символу, соответствующему шестнадцатеричному числу hhhh (между 0x0000 и 0xFFFF). |
| \0ooo (т.е., \ноль ooo) | соответствует ASCII/Latin1-символу, соответствующему восьмеричному числу ooo (между 0 и 0377). |
| . (точка) | Соответствует любому символу (включая перевод строки). |
| \d | Соответствует цифре (QChar::isDigit()). |
| \D | Соответствует нецифре. |
| \s | Соответствует символу пробела (QChar::isSpace()). |
| \S | Соответствует несимволу пробела. |
| \w | Соответствует буквенному символу (QChar::isLetterOrNumber(), QChar::isMark() или '_'). |
| \W | Соответствует небуквенному символу. |
| \n | n-я ссылка обратной ссылки, например, \1, \2 и т.д. |
Примечание: Компилятор C++ преобразует обратные косые черты в строках. Чтобы включить \ в регулярное выражение, введите его дважды, т.е. \\. Чтобы найти сам символ обратной косой черты, введите его четыре раза, т.е. \\\\.
Наборы символов
Квадратные скобки означают поиск любого символа, содержащегося в квадратных скобках. Приведенные выше сокращения для набора символов могут появляться в наборе символов в квадратных скобках. За исключением сокращений для набора символов и двух исключений, символы не имеют специального значения в квадратных скобках.
| ^ | Символ крышки инвертирует набор символов, если он встречается в качестве первого символа (т.е. сразу после открывающей квадратной скобки). [abc] соответствует 'a' или 'b' или 'c', но [^abc] соответствует любому символу, кроме 'a' или 'b' или 'c'. |
| - | Дефис указывает диапазон символов. [W-Z] соответствует 'W' или 'X' или 'Y' или 'Z'. |
Использование предварительно определенных сокращений для набора символов более портативное, чем использование диапазонов символов на разных платформах и языках. Например, [0-9] соответствует цифре в западных алфавитах, но \d соответствует цифре в любом алфавите.
Примечание: в других документациях по регулярным выражениям наборы символов часто называют «классами символов».
Квантификаторы
По умолчанию выражение автоматически квантифицируется с помощью {1,1}, т.е. оно должно встречаться ровно один раз. В приведенном ниже списке E обозначает выражение. Выражение — это символ или сокращение для набора символов или набор символов в квадратных скобках или выражение в скобках.
| E? | Соответствует нулю или одному вхождению E. Этот квантификатор означает, что предыдущее выражение необязательно, поскольку он будет соответствовать, найдено ли выражение или нет. E? — то же самое, что и E{0,1}. Например, dents? соответствует 'dent' или 'dents'. |
| E+ | Соответствует одному или более вхождениям E. E+ — то же самое, что и E{1,}. Например, 0+ соответствует '0', '00', '000' и т.д. |
| E* | Соответствует нулю или более вхождениям E. Оно равно E{0,}. Квантификатор * часто используется вместо +. Например, если \s*$ используется в выражении для поиска строк, заканчивающихся пробелом, оно будет соответствовать каждой строке, так как \s*$ означает Найдите ноль или более пробелов, за которым следует конец строки. Правильное регулярное выражение для поиска строк, имеющих по крайней мере один конечный символ пробела, — \s+$. |
| E{n} | Соответствует ровно n вхождениям E. E{n} равно повторению E n раз. Например, x{5} равно xxxxx. Оно также равно E{n,n}, например, x{5,5}. |
| E{n,} | Соответствует по крайней мере n вхождениям E. |
| E{,m} | Соответствует не более m вхождениям E. E{,m} равно E{0,m}. |
| E{n,m} | Соответствует по крайней мере n и не более m вхождениям E. |
Для применения квантификатора к большему, чем просто предшествующий символ, используйте скобки для группирования символов в выражении. Например, tag+ соответствует 't', за которым следует 'a', за которым следует по крайней мере один 'g', в то время как (tag)+ соответствует по крайней мере одному вхождению 'tag'.
Примечание: квантификаторы обычно являются «жадными». Они всегда соответствуют как можно большему количеству текста. Например, 0+ соответствует первой найденной нулю и всем последующим нулям после первой нули. При применении к '20005' он соответствует '20005'. Квантификаторы могут быть сделаны ленивыми, см. setMinimal().
Извлечение текста
Скобки позволяют нам группировать элементы вместе, чтобы мы могли их количественно оценить и захватить. Например, если у нас есть выражение mail|letter|correspondence, которое соответствует строке, мы знаем, что один из слов соответствует, но не знаем, какое именно. Использование скобок позволяет нам «захватить» всё, что соответствует внутри них, поэтому если мы использовали (mail|letter|correspondence) и сопоставили этот регулярный выражение строке «I sent you some email», мы можем использовать функции cap() или capturedTexts() для извлечения соответствующих символов, в данном случае 'mail'.
Мы можем использовать захваченный текст внутри самого регулярного выражения. Для ссылки на захваченный текст мы используем обратные ссылки, которые нумеруются с 1, так же как и для cap(). Например, мы могли бы искать дублирующиеся слова в строке, используя \b(\w+)\W+\1\b, что означает сопоставить границу слова, за которой следует одно или несколько символов слова, за которыми следует одно или несколько несловообразующих символов, за которыми следует тот же текст, что и в первой скобке, за которым следует граница слова.
Если мы хотим использовать скобки только для группирования, а не для захвата, мы можем использовать незахватывающий синтаксис, например, (?:green|blue). Незахватывающие скобки начинаются '(?:' и заканчиваются ')'. В этом примере мы сопоставляем либо 'green', либо 'blue', но не захватываем соответствие, поэтому мы знаем только, сопоставилось ли это или нет, но не знаем, какой цвет мы на самом деле нашли. Использование незахватывающих скобок более эффективно, чем использование захватывающих скобок, так как двигателю регулярных выражений нужно меньше работы по ведению записей.
Захватывающие и незахватывающие скобки могут быть вложены.
По историческим причинам квантификаторы (например, *), которые применяются к захватывающим скобкам, более «жадные», чем другие квантификаторы. Например, a*(a*) будет соответствовать "aaa" с cap(1) == "aaa". Это поведение отличается от того, что делают другие движки регулярных выражений (в частности, Perl). Чтобы получить более интуитивное поведение захвата, укажите QRegExp::RegExp2 в конструктор QRegExp или вызовите setPatternSyntax(QRegExp::RegExp2).
Когда количество совпадений заранее неизвестно, распространённым приёмом является использование cap() в цикле. Например:
QRegExp rx("(\\d+)");
QString str = "Offsets: 12 14 99 231 7";
QStringList list;
int pos = 0;
while ((pos = rx.indexIn(str, pos)) != -1) {
list << rx.cap(1);
pos += rx.matchedLength();
}
// list: ["12", "14", "99", "231", "7"] Утверждения
Утверждения делают какое-то утверждение о тексте в той точке, где они встречаются в регулярном выражении, но они не сопоставляют никаких символов. В следующем списке E обозначает любое выражение.
| ^ | Знак ^ обозначает начало строки. Если вы хотите сопоставить буквальную ^ , вы должны экранировать её, написав \\^. Например, ^#include будет соответствовать только строкам, которые начинаются с символов '#include'. (Когда символ ^ является первым символом в наборе символов, он имеет особое значение, см. Наборы символов.) |
| $ | Символ $ обозначает конец строки. Например, \d\s*$ будет соответствовать строкам, которые оканчиваются цифрой, за которой необязательно следует пробел. Если вы хотите сопоставить буквальную $ , вы должны экранировать её, написав \\$. |
| \b | Граница слова. Например, регулярное выражение \bOK\b означает сопоставить сразу после границы слова (например, начало строки или пробел) букву 'O', затем букву 'K', сразу перед другой границей слова (например, конец строки или пробел). Обратите внимание, что утверждение фактически не сопоставляет никакой пробел, поэтому если мы напишем (\bOK\b) и у нас есть соответствие, то оно будет содержать только 'OK', даже если строка — "It's OK now". |
| \B | Не-граница слова. Это утверждение истинно там, где \b ложно. Например, если мы искали \Bon\B в «Left on», соответствие не удалось бы (пробел и конец строки не являются не-границами слова), но оно соответствовало бы в «tonne». |
| (?=E) | Позитивный просмотр вперед. Это утверждение истинно, если выражение соответствует в этой точке регулярного выражения. Например, const(?=\s+char) соответствует 'const' всякий раз, когда за ним следует 'char', как в 'static const char *'. (Сравните с const\s+char, которое соответствует 'static const char *'.) |
| (?!E) | Отрицательный просмотр вперед. Это утверждение истинно, если выражение не соответствует в этой точке регулярного выражения. Например, const(?!\s+char) соответствует 'const', кроме случаев, когда за ним следует 'char'. |
Сопоставление с подстановкой
Большинство командных оболочек, таких как bash или cmd.exe, поддерживают «глобальный поиск файлов», возможность идентификации группы файлов с использованием подстановочных символов. Функция setPatternSyntax() используется для переключения между режимом регулярных выражений и режимом подстановочных символов. Сопоставление с подстановкой гораздо проще, чем полные регулярные выражения, и имеет только четыре функции:
| c | Любой символ представляет сам себя, кроме упомянутых ниже. Таким образом, c соответствует символу c. |
| ? | Соответствует любому одиночному символу. Это то же самое, что и . в полных регулярных выражениях. |
| * | Соответствует нулю или более любым символам. Это то же самое, что и .* в полных регулярных выражениях. |
| [...] | Наборы символов могут быть представлены в квадратных скобках, подобно полным регулярным выражениям. Внутри набора символов, как и снаружи, обратный слэш не имеет особого значения. |
В режиме «Подстановка» символы подстановки не могут быть экранированы. В режиме WildcardUnix символ '\' экранирует подстановочный символ.
Например, если мы находимся в режиме подстановки и имеем строки, содержащие имена файлов, мы могли бы идентифицировать файлы HTML с помощью *.html. Это будет соответствовать нулю или более символам, за которыми следует точка, за которой следуют 'h', 't', 'm' и 'l'.
Для проверки строки на соответствие выражению с подстановкой используйте exactMatch(). Например:
QRegExp rx("*.txt");
rx.setPatternSyntax(QRegExp::Wildcard);
rx.exactMatch("README.txt"); // returns true
rx.exactMatch("welcome.txt.bak"); // returns false Примечания для пользователей Perl
Большинство сокращений наборов символов, поддерживаемых Perl, поддерживаются QRegExp, см. символы и сокращения для наборов символов.
В QRegExp, за исключением наборов символов, ^ всегда обозначает начало строки, поэтому знаки ^ всегда должны экранироваться, если не используются для этой цели. В Perl значение знака ^ автоматически изменяется в зависимости от того, где он находится, поэтому экранирование его редко необходимо. То же самое относится к $ , которое в QRegExp всегда обозначает конец строки.
Квантификаторы QRegExp такие же, как жадные квантификаторы Perl (но см. примечание выше). Нежадное сопоставление не может быть применено к отдельным квантификаторам, но может быть применено ко всем квантификаторам в шаблоне. Например, для сопоставления регулярного выражения Perl ro+?m требуется:
QRegExp rx("ro+m");
rx.setMinimal(true); Эквивалент опции Perl /i — setCaseSensitivity(Qt::CaseInsensitive).
Опция Perl /g может быть эмулирована с помощью цикла.
В QRegExp . соответствует любому символу, поэтому все регулярные выражения QRegExp имеют эквивалент опции Perl /s . QRegExp не имеет эквивалента опции Perl /m , но это можно смоделировать различными способами, например, разделив входные данные на строки или выполнив цикл с регулярным выражением, которое ищет новые строки.
Поскольку QRegExp ориентирована на строки, утверждений \A, \Z или \z нет. Утверждение \G не поддерживается, но может быть эмулировано в цикле.
Perl's $& — это cap(0) или capturedTexts()[0]. Эквивалентов $`, $' или $+ в QRegExp нет. Переменные захвата Perl $1, $2... соответствуют cap(1) или capturedTexts()[1], cap(2) или capturedTexts()[2] и т. д.
Для подстановки шаблона используйте QString::replace().
Расширенный синтаксис /x Perl не поддерживается, как и директивы, например, (?i), или комментарии к регулярным выражениям, например, (?#comment). С другой стороны, правила C++ для литеральных строк можно использовать для достижения того же:
QRegExp mark("\\b" // word boundary
"[Mm]ark" // the word we want to match
); Поддерживаются утверждения положительного и отрицательного просмотра с нулевой шириной (?=шаблон) и (?!шаблон) с тем же синтаксисом, что и в Perl. Утверждения Perl о просмотре назад, «независимые» подвыражения и условные выражения не поддерживаются.
Также поддерживаются незахватывающие скобки с тем же синтаксисом (?:шаблон).
См. QString::split() и QStringList::join() для эквивалентов функций Perl split и join.
Примечание: поскольку C++ преобразует обратные слэши, их нужно писать дважды в коде, например, \b нужно написать \\b.
Примеры кода
QRegExp rx("^\\d\\d?$"); // match integers 0 to 99
rx.indexIn("123"); // returns -1 (no match)
rx.indexIn("-6"); // returns -1 (no match)
rx.indexIn("6"); // returns 0 (matched at position 0) Третья строка соответствует '6'. Это простое регулярное выражение для проверки целых чисел в диапазоне от 0 до 99.
QRegExp rx("^\\S+$"); // match strings without whitespace
rx.indexIn("Hello world"); // returns -1 (no match)
rx.indexIn("This_is-OK"); // returns 0 (matched at position 0) Вторая строка соответствует 'This_is-OK'. Мы использовали сокращение набора символов '\S' (непробел) и якоря для сопоставления строк, не содержащих пробелов.
В следующем примере мы сопоставляем строки, содержащие 'mail' или 'letter' или 'correspondence', но сопоставляем только целые слова, то есть не 'email'
QRegExp rx("\\b(mail|letter|correspondence)\\b");
rx.indexIn("I sent you an email"); // returns -1 (no match)
rx.indexIn("Please write the letter"); // returns 17 Вторая строка соответствует "Please write the letter". Слово 'letter' также захватывается (из-за скобок). Мы можем увидеть, какой текст мы захватили, так:
QString captured = rx.cap(1); // captured == "letter"
Это позволит захватить текст из первой пары захватывающих скобок (считая захватывающие левые скобки слева направо). Скобки считаются с 1, так как cap(0) — это всё сопоставленное регулярное выражение (эквивалент '&' в большинстве движков регулярных выражений).
QRegExp rx("&(?!amp;)"); // match ampersands but not &
QString line1 = "This & that";
line1.replace(rx, "&");
// line1 == "This & that"
QString line2 = "His & hers & theirs";
line2.replace(rx, "&");
// line2 == "His & hers & theirs" Здесь мы передали QRegExp функции replace() объекта QString для замены сопоставленного текста новым текстом.
QString str = "One Eric another Eirik, and an Ericsson. "
"How many Eiriks, Eric?";
QRegExp rx("\\b(Eric|Eirik)\\b"); // match Eric or Eirik
int pos = 0; // where we are in the string
int count = 0; // how many Eric and Eirik's we've counted
while (pos >= 0) {
pos = rx.indexIn(str, pos);
if (pos >= 0) {
++pos; // move along in str
++count; // count our Eric or Eirik
}
} Мы использовали функцию indexIn() для многократного сопоставления регулярного выражения в строке. Обратите внимание, что вместо пошагового перемещения вперёд на один символ pos++ мы могли бы написать pos += rx.matchedLength() , чтобы пропустить уже сопоставленную строку. Счёт будет равен 3, сопоставляя 'One Eric another Eirik, and an Ericsson. How many Eiriks, Eric?'; он не сопоставляет 'Ericsson' или 'Eiriks', так как они не ограничены не-границами слова.
Одно из распространённых применений регулярных выражений — разбиение строк ограниченных данных на составляющие поля.
str = "The Qt Company Ltd\tqt.io\tFinland";
QString company, web, country;
rx.setPattern("^([^\t]+)\t([^\t]+)\t([^\t]+)$");
if (rx.indexIn(str) != -1) {
company = rx.cap(1);
web = rx.cap(2);
country = rx.cap(3);
} В этом примере наши входные строки имеют формат название компании, веб-адрес и страна. К сожалению, регулярное выражение довольно длинное и не очень универсальное — код сломается, если мы добавим еще какие-либо поля. Более простое и лучшее решение — искать разделитель, в данном случае '\t', и брать окружающий текст. Функция QString::split() может принимать строку-разделитель или регулярное выражение в качестве аргумента и соответственно разделять строку.
QStringList field = str.split("\t"); Здесь field[0] — компания, field[1] — веб-адрес и так далее.
Для имитации сопоставления с оболочкой мы можем использовать режим подстановок.
QRegExp rx("*.html");
rx.setPatternSyntax(QRegExp::Wildcard);
rx.exactMatch("index.html"); // returns true
rx.exactMatch("default.htm"); // returns false
rx.exactMatch("readme.txt"); // returns false Сопоставление с подстановками может быть удобным из-за своей простоты, но любое регулярное выражение с подстановками можно определить с помощью полных регулярных выражений, например, .*\.html$. Обратите внимание, что мы не можем сопоставить оба .html и .htm файла с помощью подстановок, если не используем *.htm*, которое также будет соответствовать 'test.html.bak'. Полное регулярное выражение даёт нам необходимую точность, .*\.html?$.
QRegExp может выполнять сопоставление без учёта регистра с помощью setCaseSensitivity(), и может использовать нежадное сопоставление, см. setMinimal(). По умолчанию QRegExp использует полные регулярные выражения, но это можно изменить с помощью setPatternSyntax(). Поиск можно выполнить вперёд с помощью indexIn() или назад с помощью lastIndexIn(). Захваченный текст можно получить, используя capturedTexts(), которая возвращает список строк всех захваченных строк, или с помощью cap(), которая возвращает захваченную строку для данного индекса. Функция pos() принимает индекс совпадения и возвращает позицию в строке, где произошло совпадение (или -1, если совпадения не было).
См. также QString, QStringList, QRegExpValidator, QSortFilterProxyModel, и Пример регулярных выражений.
Документация типов членов
enum QRegExp::CaretMode
Перечисление CaretMode определяет различные значения символа «^» (^) в регулярном выражении. Возможные значения:
| Константа | Значение | Описание |
|---|---|---|
QRegExp::CaretAtZero |
0 |
Символ «^» соответствует индексу 0 в искомой строке. |
QRegExp::CaretAtOffset |
1 |
Символ «^» соответствует начальному смещению поиска. |
QRegExp::CaretWontMatch |
2 |
Символ «^» никогда не соответствует. |
enum QRegExp::PatternSyntax
Синтаксис, используемый для интерпретации значения шаблона.
| Константа | Значение | Описание |
|---|---|---|
QRegExp::RegExp |
0 |
Богатый синтаксис сопоставления с образцом, похожий на Perl. Это значение по умолчанию. |
QRegExp::RegExp2 |
3 |
Подобно RegExp, но с жадными квантификаторами. (Введено в Qt 4.2.) |
QRegExp::Wildcard |
1 |
Это обеспечивает простой синтаксис сопоставления с образцом, похожий на используемый оболочками (интерпретаторами команд) для «сопоставления файлов». См. сопоставление QRegExp с подстановками. |
QRegExp::WildcardUnix |
4 |
Это аналогично Wildcard, но с поведением оболочки Unix. Символы подстановок можно экранировать символом «\». |
QRegExp::FixedString |
2 |
Шаблон — это фиксированная строка. Это эквивалентно использованию шаблона RegExp для строки, в которой все метасимволы экранированы с помощью escape(). |
QRegExp::W3CXmlSchema11 |
5 |
Шаблон — это регулярное выражение, как определено спецификацией W3C XML Schema 1.1. |
См. также setPatternSyntax().
Документация функций-членов
QRegExp::QRegExp(const QRegExp &rx)
Создаёт регулярное выражение как копию rx.
См. также operator=().
QRegExp::QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive, QRegExp::PatternSyntax syntax = RegExp)
Создаёт объект регулярного выражения для данной строки pattern. Шаблон должен быть задан с использованием обозначения подстановок, если syntax — Wildcard; по умолчанию — RegExp. Шаблон чувствителен к регистру, если cs — Qt::CaseInsensitive. Сопоставление жадное (максимальное), но его можно изменить, вызвав setMinimal().
См. также setPattern(), setCaseSensitivity() и setPatternSyntax().
QRegExp::QRegExp()
Создаёт пустое регулярное выражение.
См. также isValid() и errorString().
QRegExp &QRegExp::operator=(QRegExp &&other)
Перемещает other в этот экземпляр QRegExp.
Эта функция была введена в Qt 5.2.
QRegExp &QRegExp::operator=(const QRegExp &rx)
Копирует регулярное выражение rx и возвращает ссылку на копию. Также копируются настройки чувствительности к регистру, подстановок и минимального сопоставления.
QRegExp::~QRegExp()
Удаляет регулярное выражение и очищает его внутренние данные.
QString QRegExp::cap(int nth = 0) const
Возвращает текст, захваченный подвыражением nth. Полное совпадение имеет индекс 0, а подвыражения в скобках имеют индексы, начиная с 1 (исключая незахватывающие скобки).
QRegExp rxlen("(\\d+)(?:\\s*)(cm|inch)");
int pos = rxlen.indexIn("Length: 189cm");
if (pos > -1) {
QString value = rxlen.cap(1); // "189"
QString unit = rxlen.cap(2); // "cm"
// ...
} Порядок элементов, сопоставленных функцией cap(), таков. Первый элемент, cap(0), — это вся строка совпадения. Каждый последующий элемент соответствует следующей открывающей захватывающей левой скобке. Таким образом, cap(1) — это текст первой захватывающей скобки, cap(2) — текст второй и так далее.
См. также capturedTexts() и pos().
int QRegExp::captureCount() const
Возвращает количество захватов, содержащихся в регулярном выражении.
Эта функция была введена в Qt 4.6.
QStringList QRegExp::capturedTexts() const
Возвращает список захваченных строк.
Первая строка в списке — это вся сопоставленная строка. Каждый последующий элемент списка содержит строку, которая соответствовала подвыражению (захвата) регулярного выражения.
Например:
QRegExp rx("(\\d+)(\\s*)(cm|inch(es)?)");
int pos = rx.indexIn("Length: 36 inches");
QStringList list = rx.capturedTexts();
// list is now ("36 inches", "36", " ", "inches", "es") В приведенном выше примере также захватываются элементы, которые могут присутствовать, но нам не интересны. Эту проблему можно решить, используя незахватывающие скобки:
QRegExp rx("(\\d+)(?:\\s*)(cm|inch(?:es)?)");
int pos = rx.indexIn("Length: 36 inches");
QStringList list = rx.capturedTexts();
// list is now ("36 inches", "36", "inches") Обратите внимание, что если вы хотите пройти по списку, вы должны пройти по его копии, например.
QStringList list = rx.capturedTexts();
QStringList::iterator it = list.begin();
while (it != list.end()) {
myProcessing(*it);
++it;
} Некоторые регулярные выражения могут соответствовать неопределённому количеству раз. Например, если входная строка — "Сдвиги: 12 14 99 231 7", и регулярное выражение — rx, — (\d+)+, мы надеемся получить список всех сопоставленных чисел. Однако после вызова rx.indexIn(str), capturedTexts() вернёт список ("12", "12"), то есть всё совпадение было "12", и первое подвыражение совпало с "12". Правильный подход — использовать cap() в цикле.
Порядок элементов в списке строк таков. Первый элемент — это вся строка совпадения. Каждый последующий элемент соответствует следующей открывающей захватывающей левой скобке. Таким образом, capturedTexts()[1] — это текст первой захватывающей скобки, capturedTexts()[2] — это текст второй и так далее (соответствующее $1, $2 и т.д. в некоторых других языках регулярных выражений).
Qt::CaseSensitivity QRegExp::caseSensitivity() const
Возвращает Qt::CaseSensitive, если регулярное выражение сопоставляется с учётом регистра; в противном случае возвращает Qt::CaseInsensitive.
См. также setCaseSensitivity(), patternSyntax(), pattern() и isMinimal().
QString QRegExp::errorString() const
Возвращает строку текста, объясняющую, почему шаблон регулярного выражения недействителен в случае; в противном случае возвращает "ошибка не произошла".
См. также isValid().
[static] QString QRegExp::escape(const QString &str)
Возвращает строку str с каждым специальным символом регулярного выражения экранированным обратной косой чертой. Специальные символы: $, (,), *, +, ., ?, [, ], ^, {, | и }.
Пример:
s1 = QRegExp::escape("bingo"); // s1 == "bingo"
s2 = QRegExp::escape("f(x)"); // s2 == "f\\(x\\)" Эта функция полезна для динамического построения шаблонов регулярных выражений:
QRegExp rx("(" + QRegExp::escape(name) +
"|" + QRegExp::escape(alias) + ")"); См. также setPatternSyntax().
bool QRegExp::exactMatch(const QString &str) const
Возвращает true если str точно соответствует этому регулярному выражению; в противном случае возвращает false. Вы можете определить, сколько символов строки было сопоставлено, вызвав matchedLength().
Для заданной строки регулярного выражения R, exactMatch("R") эквивалентно indexIn("^R$") так как exactMatch() эффективно включает регулярное выражение в якоря начала и конца строки, за исключением того, что она устанавливает matchedLength() по-другому.
Например, если регулярное выражение — blue, то exactMatch() возвращает true только для входной строки blue. Для входных строк bluebell, blutak и lightblue, exactMatch() возвращает false и matchedLength() вернёт соответственно 4, 3 и 0.
Несмотря на то, что функция является константной, она устанавливает значения matchedLength(), capturedTexts() и pos().
См. также indexIn() и lastIndexIn().
int QRegExp::indexIn(const QString &str, int offset = 0, QRegExp::CaretMode caretMode = CaretAtZero) const
Попытка найти совпадение в str с позиции offset (по умолчанию 0). Если offset равно -1, поиск начинается с последнего символа; если -2, со второго последнего символа и т. д.
Возвращает позицию первого совпадения или -1, если совпадений нет.
Параметр caretMode позволяет указать, должно ли ^ соответствовать индексу 0 или offset.
Возможно, вы предпочтёте использовать QString::indexOf(), QString::contains() или даже QStringList::filter(). Для замены совпадений используйте QString::replace().
Пример:
QString str = "offsets: 1.23 .50 71.00 6.00";
QRegExp rx("\\d*\\.\\d+"); // primitive floating point matching
int count = 0;
int pos = 0;
while ((pos = rx.indexIn(str, pos)) != -1) {
++count;
pos += rx.matchedLength();
}
// pos will be 9, 14, 18 and finally 24; count will end up as 4 Несмотря на то, что функция является константной, она устанавливает значения matchedLength(), capturedTexts() и pos().
Если регулярное выражение QRegExp представляет собой шаблон подстановки (см. setPatternSyntax()), и необходимо проверить строку на соответствие всему шаблону подстановки, используйте exactMatch() вместо этой функции.
См. также lastIndexIn() и exactMatch().
bool QRegExp::isEmpty() const
Возвращает true если строка шаблона пуста; в противном случае возвращает false.
Если вы вызываете exactMatch() с пустым шаблоном на пустой строке, она вернёт true; в противном случае вернёт false так как она работает над всей строкой. Если вы вызываете indexIn() с пустым шаблоном для любой строки, она вернёт начальную позицию (0 по умолчанию), потому что пустой шаблон соответствует «пустоте» в начале строки. В этом случае длина совпадения, возвращаемая matchedLength(), будет 0.
См. QString::isEmpty().
bool QRegExp::isMinimal() const
Возвращает true если включено минимальное (нежадное) сопоставление; в противном случае возвращает false.
См. также caseSensitivity() и setMinimal().
bool QRegExp::isValid() const
Возвращает true если регулярное выражение является допустимым; в противном случае возвращает false. Недопустимое регулярное выражение никогда не соответствует.
Шаблон [a-z является примером недопустимого шаблона, так как ему не хватает закрывающей квадратной скобки.
Обратите внимание, что допустимость регулярного выражения также может зависеть от флага шаблона подстановки, например, *.html — это допустимое регулярное выражение шаблона подстановки, но недопустимое полное регулярное выражение.
См. также errorString().
int QRegExp::lastIndexIn(const QString &str, int offset = -1, QRegExp::CaretMode caretMode = CaretAtZero) const
Попытка найти совпадение в обратном направлении в str с позиции offset. Если offset равно -1 (по умолчанию), поиск начинается с последнего символа; если -2, со второго последнего символа и т. д.
Возвращает позицию первого совпадения или -1, если совпадений нет.
Параметр caretMode позволяет указать, должно ли ^ соответствовать индексу 0 или offset.
Несмотря на то, что функция является константной, она устанавливает значения matchedLength(), capturedTexts() и pos().
Предупреждение: Поиск назад значительно медленнее, чем поиск вперёд.
См. также indexIn() и exactMatch().
int QRegExp::matchedLength() const
Возвращает длину последней сопоставленной строки или -1, если совпадений не было.
См. также exactMatch(), indexIn() и lastIndexIn().
QString QRegExp::pattern() const
Возвращает строку шаблона регулярного выражения. Шаблон имеет синтаксис регулярного выражения или шаблон подстановки в зависимости от patternSyntax().
См. также setPattern(), patternSyntax() и caseSensitivity().
QRegExp::PatternSyntax QRegExp::patternSyntax() const
Возвращает синтаксис, используемый в регулярном выражении. По умолчанию — QRegExp::RegExp.
См. также setPatternSyntax(), pattern() и caseSensitivity().
int QRegExp::pos(int nth = 0) const
Возвращает позицию nth захваченного текста в строке поиска. Если nth равно 0 (по умолчанию), pos() возвращает позицию всего совпадения.
Пример:
QRegExp rx("/([a-z]+)/([a-z]+)");
rx.indexIn("Output /dev/null"); // returns 7 (position of /dev/null)
rx.pos(0); // returns 7 (position of /dev/null)
rx.pos(1); // returns 8 (position of dev)
rx.pos(2); // returns 12 (position of null) Для совпадений длиной 0 pos() всегда возвращает -1. (Например, если cap(4) вернёт пустую строку, pos(4) вернёт -1.) Это особенность реализации.
См. также cap() и capturedTexts().
void QRegExp::setCaseSensitivity(Qt::CaseSensitivity cs)
Устанавливает чувствительность к регистру на cs.
Если cs равно Qt::CaseSensitive, \.txt$ соответствует readme.txt но не соответствует README.TXT.
См. также caseSensitivity(), setPatternSyntax(), setPattern() и setMinimal().
void QRegExp::setMinimal(bool minimal)
Включает или выключает минимальное сопоставление. Если minimal равно false, сопоставление является жадным (максимальным), что является значением по умолчанию.
Например, предположим, что у нас есть строка «Мы должны быть <b>смелыми</b>, очень <b>смелыми</b>!» и шаблон <b>.*</b>. С использованием жадного (максимального) сопоставления по умолчанию совпадение равно «Мы должны быть <b>смелыми</b>, очень <b>смелыми</b>!». Но с минимальным (нежадным) сопоставлением первое совпадение равно «Мы должны быть <b>смелыми</b>, очень <b>смелыми</b>!», а второе совпадение равно «Мы должны быть <b>смелыми</b>, очень <b>смелыми</b>!». На практике мы, возможно, будем использовать шаблон <b>[^<]*</b> вместо него, хотя это всё равно не сработает для вложенных тегов.
См. также isMinimal() и setCaseSensitivity().
void QRegExp::setPattern(const QString &pattern)
Устанавливает строку шаблона на pattern. Чувствительность к регистру, шаблоны подстановки и минимальное сопоставление не изменяются.
См. также pattern(), setPatternSyntax() и setCaseSensitivity().
void QRegExp::setPatternSyntax(QRegExp::PatternSyntax syntax)
Устанавливает режим синтаксиса для регулярного выражения. По умолчанию — QRegExp::RegExp.
Указание syntax в QRegExp::Wildcard включает простые шаблоны подстановки в стиле оболочки. Например, r*.txt соответствует строке readme.txt в режиме шаблона подстановки, но не соответствует readme.
Указание syntax в QRegExp::FixedString означает, что шаблон интерпретируется как обычная строка. Специальные символы (например, обратный слеш) при этом не нужно экранировать.
См. также patternSyntax(), setPattern(), setCaseSensitivity() и escape().
void QRegExp::swap(QRegExp &other)
Заменяет регулярное выражение other этим регулярным выражением. Данная операция очень быстрая и никогда не терпит неудачу.
Эта функция была добавлена в Qt 4.8.
bool QRegExp::operator!=(const QRegExp &rx) const
Возвращает true если это регулярное выражение не равно rx; в противном случае возвращает false.
См. также operator==().
bool QRegExp::operator==(const QRegExp &rx) const
Возвращает true если это регулярное выражение равно rx; в противном случае возвращает false.
Два объекта QRegExp равны, если у них одинаковые строки шаблонов и одинаковые настройки для чувствительности к регистру, подстановочных символов и минимального сопоставления.
Связанные нечленные функции
uint qHash(const QRegExp &key, uint seed = 0)
Возвращает хэш-значение для key, используя seed для инициализации вычисления.
Эта функция была добавлена в Qt 5.6.
QDataStream &operator<<(QDataStream &out, const QRegExp ®Exp)
Записывает регулярное выражение regExp в поток out.
См. также Сериализация типов данных Qt.
QDataStream &operator>>(QDataStream &in, QRegExp ®Exp)
Читает регулярное выражение из потока in в regExp.
См. также Сериализация типов данных Qt.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/qregexp.html