Класс QRegExp
Класс QRegExp предоставляет сопоставление шаблонов с использованием регулярных выражений. Подробнее...
| Заголовок: | #include <QRegExp> |
| qmake: | QT += core |
Примечание: Все функции в этом классе являются реентерабельными.
Типы public
| Перечисление | CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch } |
| Перечисление | PatternSyntax { RegExp, RegExp2, Wildcard, WildcardUnix, FixedString, W3CXmlSchema11 } |
Функции public
| 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 |
Статические члены public
| 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 можно использовать для определения того, где следует разделить строку, например, для разделения строк, разделенных табуляцией. |
Приводится краткое введение в regexps, описание языка regexps Qt, несколько примеров и сама документация функций. QRegExp моделируется по языку regexp Perl. Он полностью поддерживает Unicode. QRegExp также может использоваться в более простом режиме подстановок, который похож на функциональность, встречающуюся в командных оболочках. Правила синтаксиса, используемые QRegExp, могут быть изменены с помощью setPatternSyntax(). В частности, синтаксис шаблона может быть установлен на QRegExp::FixedString, что означает, что шаблон для сопоставления интерпретируется как обычная строка, т. е. специальные символы (например, обратная косая черта) не экранируются.
Хорошая книга о regexps — это Mastering Regular Expressions (Третье издание) Джеффри Е. Ф. Фридла, ISBN 0-596-52812-4.
Примечание: В Qt 5 новый класс QRegularExpression предоставляет совместимую с Perl реализацию регулярных выражений и рекомендуется вместо QRegExp.
Введение
Regexps строятся из выражений, квантификаторов и утверждений. Самое простое выражение — это символ, например x или 5. Выражение также может быть набором символов, заключенных в квадратные скобки. [ABCD] будет соответствовать A или B или C или D. Мы можем записать это же выражение как [A-D], а выражение для сопоставления любой заглавной буквы английского алфавита записывается как [A-Z].
Квантификатор указывает количество вхождений выражения, которые должны быть сопоставлены. x{1,1} означает сопоставление одного и только одного x. x{1,5} означает сопоставление последовательности символов x, содержащей как минимум один x, но не более пяти.
Обратите внимание, что в общем случае regexps нельзя использовать для проверки скобок или тегов. Например, можно написать 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().
Расширенный синтаксис регулярных выражений Perl /x не поддерживается, а также директивы, например, (?i), или комментарии к регулярному выражению, например, (?#comment). С другой стороны, правила C++ для строковых литералов могут быть использованы для достижения того же результата:
QRegExp mark("\\b" // word boundary
"[Mm]ark" // the word we want to match
); Поддерживаются утверждения с нулевой шириной как для положительного, так и для отрицательного просмотра вперед (?=pattern) и (?!pattern) с тем же синтаксисом, что и в Perl. Утверждения Perl для просмотра назад, «независимые» подвыражения и условные выражения не поддерживаются.
Также поддерживаются незахватывающие скобки с тем же синтаксисом (?:pattern).
См. 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 в функцию QString replace() для замены сопоставленного текста новым текстом.
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() , чтобы пропустить уже сопоставленную строку. Значение count будет равно 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"); Здесь поле[0] — это компания, поле[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 |
Аналогично подстановке, но с поведением оболочки 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, если regexp соответствует регистру; в противном случае возвращает Qt::CaseInsensitive.
См. также setCaseSensitivity(), patternSyntax(), pattern() и isMinimal().
QString QRegExp::errorString() const
Возвращает строку текста, объясняющую, почему шаблон regexp недействителен; в противном случае возвращает «ошибка не произошла».
См. также isValid().
[static] QString QRegExp::escape(const QString &str)
Возвращает строку str, в которой каждый специальный символ regexp экранирован обратной косой чертой. Специальные символы — $, (,), *, +, ., ?, [, ], ^, {, | и }.
Пример:
s1 = QRegExp::escape("bingo"); // s1 == "bingo"
s2 = QRegExp::escape("f(x)"); // s2 == "f\\(x\\)" Эта функция полезна для динамического построения шаблонов regexp:
QRegExp rx("(" + QRegExp::escape(name) +
"|" + QRegExp::escape(alias) + ")"); См. также setPatternSyntax().
bool QRegExp::exactMatch(const QString &str) const
Возвращает true если str точно соответствует данному регулярному выражению; в противном случае возвращает false. Вы можете определить, сколько символов строки было сопоставлено, вызвав matchedLength().
Для данного regexp-строки R, exactMatch("R") эквивалентно indexIn("^R$") поскольку exactMatch() фактически включает regexp в якоря начала и конца строки, за исключением того, что он по-другому устанавливает 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 — пример невалидного шаблона, поскольку отсутствует закрывающая квадратная скобка.
Обратите внимание, что валидность regexp может также зависеть от флага подстановок, например, *.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, соответствие жадное (максимальное), что является значением по умолчанию.
Например, предположим, что у нас есть входная строка "We must be <b>bold</b>, very <b>bold</b>!" и шаблон <b>.*</b>. При стандартном жадном (максимальном) сопоставлении соответствием является "We must be <b>bold</b>, very <b>bold</b>!". Но при минимальном (не жадном) сопоставлении первое соответствие — "We must be <b>bold</b>, very <b>bold</b>!" и второе соответствие — "We must be <b>bold</b>, very <b>bold</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().
END_OF_DOCUMENT_MARKERvoid 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 QRegExp::qHash(const QRegExp &key, uint seed = 0)
Возвращает значение хэша для key, используя seed для инициализации вычисления.
Эта функция была добавлена в Qt 5.6.
QDataStream &QRegExp::operator<<(QDataStream &out, const QRegExp ®Exp)
Записывает регулярное выражение regExp в поток out.
См. также Сериализация типов данных Qt.
QDataStream &QRegExp::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.13/qregexp.html