Spec-Zone.ru › Qt 5.11

Класс QRegExp

Класс QRegExp предоставляет сопоставление с образцом с использованием регулярных выражений. Подробнее...

Заголовок: #include <QRegExp>
qmake: QT += core
  • Список всех членов, включая унаследованные

Примечание: Все функции в этом классе являются перестраиваемыми.

Открытые типы

Перечисление CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch }
Перечисление PatternSyntax { RegExp, RegExp2, Wildcard, WildcardUnix, FixedString, W3CXmlSchema11 }

Открытые функции

QRegExp()
QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive, QRegExp::PatternSyntax syntax = RegExp)
QRegExp(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
QRegExp & operator=(const QRegExp &rx)
QRegExp & operator=(QRegExp &&other)
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 &regExp)
QDataStream & operator>>(QDataStream &in, QRegExp &regExp)

Подробное описание

Класс QRegExp обеспечивает сопоставление шаблонов с помощью регулярных выражений.

Регулярное выражение, или "regexp", представляет собой шаблон для сопоставления подстрок в тексте. Это полезно во многих контекстах, например:

Валидация Regexp может проверить, соответствует ли подстрока определённым критериям, например, является ли она целым числом или не содержит пробелов.
Поиск Regexp предоставляет более мощное сопоставление шаблонов, чем простое сопоставление подстрок, например, найти одно из слов mail, letter или correspondence, но ни одно из слов email, mailman, mailer, letterbox и т. д.
Поиск и замена Regexp может заменить все вхождения подстроки другой подстрокой, например, заменить все вхождения & на &amp;, кроме случаев, когда & уже следует за amp;.
Разбиение строк Regexp может быть использован для определения мест, где строка должна быть разделена, например, для разделения строк, разделённых табуляцией.

Приведён краткий вводный материал по regexp, описание языка regexp в Qt, несколько примеров и сама документация функций. QRegExp основан на языке regexp языка Perl. Он полностью поддерживает Unicode. QRegExp также может быть использован в более простом режиме "шаблонов" (wildcard mode), который аналогичен функциональности, предоставляемой командными оболочками. Правила синтаксиса, используемые 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-сущность &amp;, регулярное выражение для поиска просто &. Но это регулярное выражение также будет соответствовать амперсандам, которые уже были преобразованы в 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's /i — setCaseSensitivity(Qt::CaseInsensitive).

Опция Perl's /g может быть эмулирована с помощью цикла.

В QRegExp . соответствует любому символу, поэтому все регулярные выражения QRegExp имеют эквивалент опции Perl's /s . QRegExp не имеет эквивалента опции Perl's /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 не поддерживаются утверждения lookbehind, «независимые» подвыражения и условные выражения.

Также поддерживаются незахватывающие скобки с тем же синтаксисом (?:шаблон).

См. QString::split() и QStringList::join() для эквивалентов функций split и join Perl.

Примечание: поскольку 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

Вторая строка соответствует «Пожалуйста, напишите письмо». Слово «письмо» также захватывается (из-за скобок). Мы можем увидеть, какой текст мы захватили так:

QString captured = rx.cap(1); // captured == "letter"

Это позволит захватить текст из первой пары захватывающих скобок (считая захватывающие левые скобки слева направо). Скобки считаются с 1, так как cap(0) — это всё совпавшее регулярное выражение (эквивалент '&' в большинстве движков регулярных выражений).

QRegExp rx("&(?!amp;)");      // match ampersands but not &amp;
QString line1 = "This & that";
line1.replace(rx, "&amp;");
// line1 == "This &amp; that"
QString line2 = "His &amp; hers & theirs";
line2.replace(rx, "&amp;");
// line2 == "His &amp; hers &amp; 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()

Создаёт пустое регулярное выражение.

См. также isValid() и errorString().

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(const QRegExp &rx)

Создаёт регулярное выражение как копию rx.

См. также operator=().

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;
}

Некоторые регулярные выражения могут совпадать неопределённое количество раз. Например, если входная строка — "Offsets: 12 14 99 231 7", а регулярное выражение — rx, (\d+)+, мы надеемся получить список всех сопоставленных чисел. Однако после вызова rx.indexIn(str), capturedTexts() вернёт список ("12", "12"), т. е. полное совпадение было "12", а первое подвыражение совпало с "12". Правильный подход — использовать cap() в цикле.

Порядок элементов в списке строк следующий. Первый элемент — это вся сопоставленная строка. Каждый последующий элемент соответствует следующей открывающей левой скобке. Таким образом, capturedTexts()[1] — это текст первой захватывающей скобки, capturedTexts()[2] — это текст второй и так далее (соответствующее $1, $2 и т. д. в других языках регулярных выражений).

См. также cap() и pos().

Qt::CaseSensitivity QRegExp::caseSensitivity() const

Возвращает Qt::CaseSensitive, если regexp соответствует регистру; в противном случае возвращает 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().

END_OF_DOCUMENT_MARKER

Для заданной строки регулярного выражения R, exactMatch("R") эквивалентно indexIn("^R$") так как exactMatch() эффективно заключает регулярное выражение в якоря начала и конца строки, за исключением того, что оно устанавливает matchedLength() по-другому.

Например, если регулярное выражение — blue, то exactMatch() возвращает true только для входных данных blue. Для входных данных bluebell, blutak и lightblue, exactMatch() возвращает false и matchedLength() вернёт 4, 3 и 0 соответственно.

Несмотря на const, эта функция устанавливает 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

Несмотря на const, эта функция устанавливает 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.

Несмотря на const, эта функция устанавливает 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)

Для совпадений нулевой длины 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==().

QRegExp &QRegExp::operator=(const QRegExp &rx)

Копирует регулярное выражение rx и возвращает ссылку на копию. Также копируются параметры чувствительности к регистру, подстановочных символов и минимального соответствия.

QRegExp &QRegExp::operator=(QRegExp &&other)

Перемещающее присваивание other этому экземпляру QRegExp.

Эта функция была добавлена в Qt 5.2.

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 &regExp)

Записывает регулярное выражение regExp в поток out.

См. также Сериализация типов данных Qt.

QDataStream &operator>>(QDataStream &in, QRegExp &regExp)

Читает регулярное выражение из потока in в regExp.

См. также Сериализация типов данных Qt.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/qregexp.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API