Класс QRegExp
Класс QRegExp предоставляет сопоставление шаблонов с помощью регулярных выражений. Подробнее...
| Заголовок: | #include <QRegExp> |
| qmake: | QT += core |
Примечание: Все функции в этом классе являются реентерабельными.
Типы public
| Перечисление | CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch } |
| Перечисление | PatternSyntax { RegExp, RegExp2, Wildcard, WildcardUnix, FixedString, W3CXmlSchema11 } |
Функции public
| QRegExp() | |
| QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive, 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, CaretMode caretMode = CaretAtZero) const |
| bool | isEmpty() const |
| bool | isMinimal() const |
| bool | isValid() const |
| int | lastIndexIn(const QString &str, int offset = -1, CaretMode caretMode = CaretAtZero) const |
| int | matchedLength() const |
| QString | pattern() const |
| 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(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 |
Статические 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) |
Подробное описание
Класс QRegExp предоставляет сопоставление шаблонов с помощью регулярных выражений.
Регулярное выражение, или "regexp", представляет собой шаблон для поиска подстрок в тексте. Это полезно во многих контекстах, например:
| Валидация | Regexp может проверить, соответствует ли подстрока некоторым критериям, например, является ли она целым числом или не содержит пробелов. |
| Поиск | Regexp предоставляет более мощное сопоставление шаблонов, чем просто поиск подстроки, например, найти одно из слов mail, letter или correspondence, но ни одно из слов email, mailman, mailer, letterbox и т. д. |
| Поиск и замена | Regexp может заменить все вхождения подстроки другой подстрокой, например, заменить все вхождения & на &, за исключением случаев, когда & уже последует amp;. |
| Разделение строк | Regexp может использоваться для определения мест, где следует разделить строку, например, разделение табулированных строк. |
Представлено краткое введение в regexp, описание языка regexp Qt, несколько примеров и сама документация функций. QRegExp смоделирован по языку regexp Perl. Он полностью поддерживает Unicode. QRegExp также может использоваться в более простом режиме wildcard, который аналогичен функциональности, используемой в командных оболочках. Правила синтаксиса, используемые 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's квантификаторы такие же, как у Perl's жадных квантификаторов (но см. примечание выше). Нежадное сопоставление нельзя применять к отдельным квантификаторам, но можно применять ко всем квантификаторам в шаблоне. Например, чтобы сопоставить регулярное выражение 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().
Расширенный синтаксис Perl's /x не поддерживается, также как и директивы, например, (?i), или комментарии к регулярным выражениям, например, (?#comment). С другой стороны, правила C++ для строковых литералов могут быть использованы для достижения того же:
QRegExp mark("\\b" // word boundary
"[Mm]ark" // the word we want to match
); Как нулевые утверждения положительного, так и нулевые утверждения отрицательного просмотра вперёд (?=pattern) и (?!pattern) поддерживаются с тем же синтаксисом, что и в Perl. Утверждения Perl's lookbehind, "независимые" подвыражения и условные выражения не поддерживаются.
Также поддерживаются незахватывающие скобки с тем же синтаксисом (?:pattern).
См. QString::split() и QStringList::join() для эквивалентов функций split и join Perl.
Примечание: так как C++ преобразует \'s, они должны быть записаны дважды в коде, например, \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's 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() , чтобы пропустить уже сопоставленную строку. Счётчик будет равен 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, 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
Возвращает список захваченных строк.
Первая строка в списке — это вся сопоставленная строка. Каждый последующий элемент списка содержит строку, которая соответствовала (захватывающему) подвыражению regexp.
Например:
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 соответственно.
Несмотря на const, эта функция устанавливает matchedLength(), capturedTexts() и pos().
См. также indexIn() и lastIndexIn().
int QRegExp::indexIn(const QString &str, int offset = 0, 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, 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().
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(PatternSyntax syntax)
Устанавливает режим синтаксиса для регулярного выражения. По умолчанию — QRegExp::RegExp.
Установив syntax на QRegExp::Wildcard, вы включаете простые подстановки, похожие на оболочку QRegExp wildcard matching. Например, 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 ®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/archives/qt-5.6/qregexp.html