MyTetra Share
Делитесь знаниями!
О, смотри-ка какое хорошее место. Дайте два!
Регулярные выражения в Qt - класс QRegExp
04.02.2016
08:55
Текстовые метки: Qt, регулярное выражение, regular expression, regexp, регвыр, QRegExp
Раздел: Компьютер - Программирование - Регулярные выражения


Описание класса QRegExp
[Модуль QtCore]


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

#include <QRegExp>


Замечание: Все функции в этом классе реентерабельны.


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

enum

CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch }

enum

PatternSyntax { RegExp, RegExp2, Wildcard, WildcardUnix, FixedString, W3CXmlSchema11 }


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

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 )

bool

operator!= ( const QRegExp & rx ) const

QRegExp &

operator= ( const QRegExp & rx )

bool

operator== ( const QRegExp & rx ) const


Статические открытые члены

QString

escape ( const QString & str )


Связанные нечлены класса

QDataStream &

operator<< ( QDataStream & out, const QRegExp & regExp )

QDataStream &

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


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

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

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



Проверка правильности

Регулярное выражение может проверить, соответствует ли подстрока каким-либо критериям, например, целое ли она число или не содержит ли пробелов.

Поиск

Регулярное выражение предоставляет более мощные шаблоны, чем простое соответствие строки, например, соответствие одному из слов mail, letter или correspondence, но не словам email, mailman, mailer, letterbox и т.д.

Поиск и замена

Регулярное выражение может заменить все вхождения подстроки другой подстрокой, например, заменить все вхождения & на &amp;, исключая случаи, когда за & уже следует amp;.

Разделение строки

Регулярное выражение может быть использовано для определения того, где строка должна быть разделена на части, например, разделяя строку по символам табуляции.


Тут представлено краткое введение в регулярные выражения, описание языка регулярных выражений Qt, некоторые примеры и собственно описание функций. QRegExp смоделирован на основе языка регулярных выражений Perl. Он полностью поддерживает Unicode. QRegExp может быть также использован в более простом режиме подстановочных знаков, который аналогичен функциональности, найденной в командных процессорах. Синтаксические правила, используемые QRegExp, могут быть изменены при помощи setPatternSyntax(). В частности, синтаксис шаблона может быть установлен в QRegExp::FixedString, что означает, что шаблон для сопоставления трактуется как обычная строка, т.е. специальные символы (например, обратная наклонная черта) не экранируются.

Хорошим текстом о регулярных выражениях является книга Регулярные выражения (Mastering Regular Expressions) (третье издание) Джеффри Фридла (Jeffrey E. F. Friedl), ISBN 0-596-52812-4.


Введение

Регулярные выражения создаются из выражений, кванторов и утверждений. Самое простое выражение - символ, например, x или 5. Выражением может быть также набор символов, заключённый в квадратные скобки. [ABCD] будет соответствовать либо A, либо B, либо C, либо D. Мы можем записать это выражение как [A-D], а выражение, соответствующее любой заглавной букве английского алфавита, как [A-Z].

Кванторы определяют количество вхождений выражения, для которого ищется соответствие. x{1,1} означает соответствие одному и только одному x. x{1,5} означает соответствие последовательности символов x, которая содержит как минимум один x, но не более пяти.

Заметьте, что в общем регулярные выражения не могут быть использованы для проверки сбалансированности скобок или тегов. Например, регулярное выражение может быть написано для поиска соответствия открывающего <b> и закрывающего </b> HTML-тегов, если теги <b> не вложенные, но если теги <b> вложенные, то то же самое регулярное выражение будет соответствовать открывающему тегу <b> с несоответствующим ему закрывающим </b>. Для фрагмента <b>bold <b>bolder</b></b> первый <b> будет согласован с первым </b>, что не является корректным. Тем не менее, можно написать регулярное выражение, которое будет соответствовать вложенным скобкам или тегам правильно, но только в том случае, если количество уровней вложенности фиксировано и известно. Если количество вложенных уровней не фиксировано и/или не известно, то невозможно написать регулярное выражение, которое не было бы ошибочным.

Предположим, что мы хотим написать регулярное выражение для соответствия целым числам в диапазоне от 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

Символ представляет сам себя, если у него нет особого значения в регулярном выражении. Напримeр, 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 (т.е., \zero 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.

?

Соответствует любому одиночному символу. Это то же самое, что и . в полных регулярных выражениях.

*

Соответствует нулю или нескольким любым символам. Это то же самое, что и .* в полных регулярных выражениях.

[...]

Набор символов может быть представлен в квадратных скобках, подобно полным регулярным выражениям. В классе символов, как и вне его, обратная наклонная черта не имеет особого значения.

В режиме Wildcard символы подстановочных знаков не могут быть экранированы. В режиме WildcardUnix символ '\' экранирует подстановочные знаки.

Например, если мы находимся в режиме подстановочных знаков и имеем строку, которая содержит имена файлов, мы можем идентифицировать файлы с помощью *.html. Это будет соответствовать нулю или нескольким символам со следующей точкой со следующими 'h', 't', 'm' и 'l'.

Чтобы проверить строку с выражением с подстановочными знаками, используйте exactMatch(). Например:

QRegExp rx("*.txt");

rx.setPatternSyntax(QRegExp::Wildcard);

rx.exactMatch("README.txt"); // возвращает true

rx.exactMatch("welcome.txt.bak"); // возвращает 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 может быть сымитирован при помощи loop.

В QRegExp . соответствует любому символу, поэтому все регулярные выражения QRegExp имеют эквивалент параметра Perl /s. QRegExp не имеет эквивалента параметра Perl /m, но это может быть сымитировано различными способами, например, разделением входа на строки или циклом с регулярным выражением, которое ищет новую строку.

Поскольку QRegExp ориентирован на строки, то утверждения \A, \Z или \z отсутствуют. Утверждение \G не поддерживается, но может быть сымитировано в цикле.

Аналогом $& из Perl является cap(0) или capturedTexts()[0]. В QRegExp нет эквивалентов для $`, $' и $+. Захваченные Perl переменные, $1, $2, ... соответствуют cap(1) или capturedTexts()[1], cap(2) или capturedTexts()[2]и т.д.

Для замены образца используйте QString::replace().

Расширенный синтаксис Perl /x не поддерживается, равно как и директивы, например, (?i) или комментарии regexp, например, (?#comment). С другой стороны, правила C++ для символьных строк могут быть применены для достижения того же:

QRegExp mark("\\b" // граница слова

"[Mm]ark" // слово для соответствия

);

Как позитивное, так и негативное утверждения просмотра вперёд (?=pattern) и (?!pattern) поддерживаются с тем же синтаксисом, что и в Perl. Утверждения Perl просмотра назад, "независимые" подвыражения и условные выражения не поддерживаются.

Незахватывающие круглые скобки также поддерживаются, с тем же самым синтаксисом (?:pattern).

В качестве эквивалентов функциям Perl split и join смотрите QString::split() и QStringList::join().

Замечание: поскольку экранирующий \ в C должен быть записан дважды в коде, то, например, \b должно быть записано как \\b.


Примеры кода

QRegExp rx("^\\d\\d?$"); // соответствует целым от 0 до 99

rx.indexIn("123"); // возвращает -1 (нет соответствия)

rx.indexIn("-6"); // возвращает -1 (нет соответствия)

rx.indexIn("6"); // возвращает 0 (соответствие в позиции 0)

Третья строка соответствует '6'. Это простая проверка регулярного выражения на целые в диапазоне от 0 до 99.

QRegExp rx("^\\S+$"); // соответствует строке без пробельных символов

rx.indexIn("Hello world"); // возвращает -1 (нет соответствия)

rx.indexIn("This_is-OK"); // возвращает 0 (соответствие в позиции 0)

Вторая строка соответствует 'This_is-OK'. Мы использовали сокращение для набора символов '\S' (не пробельные символы) и якорь для соответствия строке, не содержащей пробельных символов.

В следующем примере мы ищем соответствие строкам, содержащим 'mail', или 'letter', или 'correspondence', но только соответствие целым словам, т.е. не 'email'.

QRegExp rx("\\b(mail|letter|correspondence)\\b");

rx.indexIn("I sent you an email"); // возвращает -1 (нет соответствия)

rx.indexIn("Please write the letter"); // возвращает 17

Вторая строка соответствует "Please write the letter". Слово 'letter' также захватывается (из-за круглых скобок). Мы можем увидеть, какой текст мы получили, подобно этому:

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

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

QRegExp rx("&(?!amp;)"); // соответствует амперсанду, но не &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 в функцию QString replace() для замены соответствующего текста на новый текст.

QString str = "One Eric another Eirik, and an Ericsson. "

"How many Eiriks, Eric?";

QRegExp rx("\\b(Eric|Eirik)\\b"); // соответствие Eric или Eirik

int pos = 0; // где мы находимся в строке

int count = 0; // подсчитываем, как много Eric и Eirik

while (pos >= 0) {

pos = rx.indexIn(str, pos);

if (pos >= 0) {

++pos; // двигаемся далее по строке

++count; // учитываем нашего Eric или Eirik

}

}

Мы использовали функцию indexIn(), чтобы повторно искать соответствие регулярного выражения в строке. Заметьте, что вместо перемещения вперёд на один символ за раз pos++ мы могли бы написать pos += rx.matchedLength(), чтобы пропустить уже соответствующие строки. Количество будет равно 3, соответствуя 'One Eric another Eirik, and an Ericsson. How many Eiriks, Eric?'; это не соответствует 'Ericsson' или 'Eiriks', поскольку они не ограничены границами слова.

Одним из распространённых применений регулярных выражений является разделение строк разграниченных данных на поля.

str = "Nokia Corporation\tqt.nokia.com\tNorway";

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"); // возвращает true

rx.exactMatch("default.htm"); // возвращает false

rx.exactMatch("readme.txt"); // возвращает false

Соответствие подстановочных знаков может быть удобным благодаря простоте, но любое регулярное выражение с подстановочными знаками может быть определено при помощи полных регулярных выражений, например, .*.html$. Заметьте, что у нас не может быть соответствия и .html, и .htm файлам при использовании подстановочных знаков, если мы не используем *.htm*, который будет также соответствовать 'test.html.bak'. Полное регулярное выражение дает нам то, что необходимо, .*\.html?$.

QRegExp может производить сравнение без учёта регистра при помощи setCaseSensitivity(), а может использовать нежадный режим соответствия, смотрите setMinimal(). По умолчанию QRegExp использует полные регулярные выражения, но это может быть изменено через setWildcard(). Поиск может осуществляться вперёд с indexIn() или назад с lastIndexIn(). Захваченный текст можно получить при помощи capturedTexts(), которая возвращает список строк из всех захваченных строк, или при помощи cap(), которая возвращает захваченную строку для указанного индекса. Функция pos() принимает индекс соответствия и возвращает позицию в строке, где произошло соответствие (или -1, если соответствий не было).

Смотрите также QString, QStringList, QRegExpValidator, QSortFilterProxyModel и Пример "Regular Expression".


Описание типов-членов

enum QRegExp::CaretMode

Перечисление CaretMode определяет различные значения каретки (^) в регулярном выражении. Возможные значения:


Константа

Значение

Описание

QRegExp::CaretAtZero

0

Каретка соответствует индексу ноль в строке поиска.

QRegExp::CaretAtOffset

1

Каретка соответствует смещению начала поиска.

QRegExp::CaretWontMatch

2

Каретка ничему не соответствует.


enum QRegExp::PatternSyntax

Синтаксис используется для интерпретации значений шаблона.


Константа

Значение

Описание

QRegExp::RegExp

0

Богатый Perl-подобный синтаксис соответствия шаблонам. Это значение по умолчанию.

QRegExp::RegExp2

3

Подобно RegExp, но с жадными кванторами. Это будет значением по умолчанию в Qt 5. (Введено в Qt 4.2.)

QRegExp::Wildcard

1

Предоставляет простой синтаксис соответствия шаблону подобно тому, как это используется в командных оболочках (командных интерпретаторах) для "подстановки файлов". Смотрите Соответствие подстановочных знаков.

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

Возвращает список захваченных текстовых строк.

Первой строкой в списке является вся соответствующая строка. Каждый последующий элемент содержит строку, соответствующую (захваченную) подвыражению в регулярном выражении.

Например:

QRegExp rx("(\\d+)(\\s*)(cm|inch(es)?)");

int pos = rx.indexIn("Length: 36 inches");

QStringList list = rx.capturedTexts();

// list теперь равен ("36 inches", "36", " ", "inches", "es")

Приведённый выше пример захватывает также те элементы, которые могут присутствовать, но в которых у нас нет интереса. Эта проблема может быть решена применением незахватывающих круглых скобок:

QRegExp rx("(\\d+)(?:\\s*)(cm|inch(?:es)?)");

int pos = rx.indexIn("Length: 36 inches");

QStringList list = rx.capturedTexts();

// list теперь равен ("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, если регулярное выражение сравнивается с учётом регистра; в противном случае возвращает Qt::CaseInsensitive.

Смотрите также setCaseSensitivity(), patternSyntax(), pattern() и isMinimal().


QString QRegExp::errorString () const

Возвращает текстовую строку, которая объясняет, почему шаблон регулярного выражения неверен в случае наличия в нём ошибки; в противном случае возвращает "no error occurred".

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


QString QRegExp::escape ( const QString & str )   [static]

Возвращает строку str, в которой каждый специальный символ регулярного выражения экранирован обратной наклонной чертой. Специальными символами являются $, (, ), *, +, ., ?, [, ], ^, {, | и }.

Пример:

s1 = QRegExp::escape("bingo"); // s1 == "bingo"

s2 = QRegExp::escape("f(x)"); // s2 == "f\\(x\\)"

Эта функция полезна при динамическом создании шаблонов регулярных выражений:

QRegExp rx("(" + QRegExp::escape(name) +

"|" + QRegExp::escape(alias) + ")");

Смотрите также setPatternSyntax().


bool QRegExp::exactMatch ( const QString & str ) const

Возвращает true, если str точно соответствует этому регулярному выражению; в противном случае возвращает false. Вы можете определить, какая длина строки соответствует, вызвав matchedLength().

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

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

Несмотря на то что функция константная, она устанавливает matchedLength(), capturedTexts() и pos().

Смотрите также indexIn() и lastIndexIn().


int QRegExp::indexIn ( const QString & str, int offset = 0, 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+"); // примитивное соответствие числам с плавающей точкой

int count = 0;

int pos = 0;

while ((pos = rx.indexIn(str, pos)) != -1) {

++count;

pos += rx.matchedLength();

}

// pos будет равен 9, 14, 18 и в завершении 24; count в конечном счёте будет равен 4

Несмотря на то что функция константная, она устанавливает matchedLength(), capturedTexts() и pos().

Если QRegExp является выражением с подстановочными знаками (смотрите setPatternSyntax()) и вы хотите протестировать строку на соответствие всему выражению, то используйте вместо этого функцию exactMatch().

Смотрите также lastIndexIn() и exactMatch().


bool QRegExp::isEmpty () const

Возвращает true, если строка шаблона пуста; в противном случае возвращает false.

Если вы вызовете exactMatch() с пустым шаблоном на пустой строке, то она вернёт true; в противном случае она вернёт false, поскольку она оперирует целой строкой. Если вы вызовете indexIn() с пустым шаблоном на любой строке, то она вернёт начальное смещение (по умолчанию 0), поскольку пустой шаблон соответствует 'пустоте' в начале строки. В этом случае длина соответствия, возвращаемая matchedLength(), будет равна 0.

Смотрите QString::isEmpty().


bool QRegExp::isMinimal () const

Возвращает true, если включено минимальное (не жадное) соответствие; в противном случае возвращает false.

Смотрите также caseSensitivity() и setMinimal().


bool QRegExp::isValid () const

Возвращает true, если регулярное выражение правильное; в противном случае возвращает false. Неправильное регулярное выражение ничему не соответствует.

Шаблон [a-z является примером неправильного шаблона, поскольку в нём отсутствует закрывающая квадратная скобка.

Заметьте, что правильность регулярного выражения может также зависеть от установки флага подстановочных знаков, например, *.html - это правильное регулярное выражение с подстановочными знаками, но неправильное полное регулярное выражение.

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


int QRegExp::lastIndexIn ( const QString & str, int offset = -1, CaretMode caretMode = CaretAtZero ) const

Пытается найти соответствие в str с позиции offset в обратном направлении. Если offset равен -1 (по умолчанию), то поиск начинается с последнего символа; если равен -2, то с предпоследнего и т.д.

Возвращает позицию первого соответствия или -1, если соответствий не было.

Параметр caretMode может быть использован для указания того, что символ ^ должен соответствовать индексу 0 или offset.

Несмотря на то что функция константная, она устанавливает matchedLength(), capturedTexts() и pos().

Предупреждение: Поиск назад более долгий, чем поиск вперёд.

Смотрите также indexIn() и exactMatch().


int QRegExp::matchedLength () const

Возвращает длину последней соответствующей строки, или -1, если соответствий не было.

Смотрите также exactMatch(), indexIn() и lastIndexIn().


QString QRegExp::pattern () const

Возвращает строку шаблона регулярного выражения. Шаблон имеет синтаксис либо регулярного выражения, либо подстановочных знаков, в зависимости от patternSyntax().

Смотрите также setPattern(), patternSyntax() и caseSensitivity().


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"); // возвращает 7 (позиция /dev/null)

rx.pos(0); // возвращает 7 (позиция /dev/null)

rx.pos(1); // возвращает 8 (позиция dev)

rx.pos(2); // возвращает 12 (позиция 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>, хотя он всё же не будет работать для вложенных тегов.

Смотрите также minimal() и setCaseSensitivity().


void QRegExp::setPattern ( const QString & pattern )

Устанавливает строку шаблона в pattern. Опции учёта регистра, подстановочных знаков и минимального соответствия не изменяются.

Смотрите также pattern(), setPatternSyntax() и setCaseSensitivity().


void QRegExp::setPatternSyntax ( PatternSyntax syntax )

Устанавливает режим синтаксиса для регулярного выражения. По умолчанию это QRegExp::RegExp.

Установка синтаксиса syntax в QRegExp::Wildcard включает простое, подобное командной оболочке, соответствие подстановочных знаков. Например, r*.txt соответствует строке readme.txt в режиме подстановочных знаков, но не соответствует readme.

Установка синтаксиса syntax в QRegExp::FixedString означает, что шаблон интерпретируется как простая строка. В этом случае специальные символы (например, обратная наклонная черта) не требуют экранирования.

Смотрите также patternSyntax(), setPattern(), setCaseSensitivity() и escape().


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

Возвращает true, если регулярное выражение не равно rx; в противном случае возвращает false.

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


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

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


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

Возвращает true, если регулярное выражение равно rx; в противном случае возвращает false.

Два объекта QRegExp равны, если они имеют одинаковую строку шаблона и одинаковые настройки учёта регистра, подстановочных знаков и минимального соответствия.


Связанные нечлены класса


QDataStream & operator<< ( QDataStream & out, const QRegExp & regExp )

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

Смотрите также Формат операторов QDataStream.


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

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


Так же в этом разделе:
← Содержание ...
 
MyTetra Share v.0.35
Яндекс индекс цитирования