|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Регулярные выражения в Qt - класс QRegExp
Время создания: 04.02.2016 08:55
Текстовые метки: Qt, регулярное выражение, regular expression, regexp, регвыр, QRegExp
Раздел: Компьютер - Программирование - Регулярные выражения
Запись: xintrea/mytetra_syncro/master/base/1454565339ebhle5k0w3/text.html на raw.github.com
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Описание класса QRegExp Класс QRegExp предоставляет сопоставление с образцом при помощи регулярных выражений. #include <QRegExp> Замечание: Все функции в этом классе реентерабельны .
Открытые типы
Открытые функции
Статические открытые члены
Связанные нечлены класса
Подробное описание Класс QRegExp предоставляет сопоставление с образцом при помощи регулярных выражений. Регулярное выражение, или "regexp", представляет собой образец для поиска соответствующей подстроки в тексте. Это полезно во многих ситуациях, например:
Здесь представлено краткое введение в регулярные выражения, описание языка регулярных выражений 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-элементом &, то регулярное выражение для поиска соответствия - просто &. Но это регулярное выражение будет также соответствовать амперсандам, которые уже были преобразованы в HTML-элементы. Мы же хотим заменить только те амперсанды, за которыми не следует amp;. Для этого нам необходимо утверждение негативного просмотра вперёд, (?!__ ). Теперь регулярное выражение может быть записано как &(?!amp;), т.е.Соответствует амперсанду, за которым не следует amp;. Если мы хотим подсчитать все вхождения 'Eric' и 'Eirik' в строке, то существует два допустимых решения: \b(Eric|Eirik)\b и \bEi?ri[ck]\b. Утверждение границы слова '\b' необходимо для предотвращения соответствия словам, которые содержат любое из имён, например 'Ericsson'. Заметьте, что второе регулярное выражение соответствует большему количеству написаний, чем мы хотели: 'Eric', 'Erik', 'Eiric' и 'Eirik'. Некоторые из рассмотренных выше примеров реализованы в разделе Примеры кода . Символы и сокращения для наборов символов
Замечание: Компиляторы C++ преобразуют обратные наклонные черты в строках. Для включения \ в регулярное выражение введите её дважды, т.е. \\. Для соответствия обратной наклонной черты самой себе введите её четыре раза, т.е. \\\\. Наборы символов Квадратные скобки означают соответствие любому символу, содержащемуся в квадратных скобках. Сокращения для наборов символов, описанные выше, могут появляться в наборе символов в квадратных скобках. За исключением сокращений для наборов символов и следующих двух исключений, у символов нет особых значений в квадратных скобках.
Использование предопределённых сокращений для наборов символов более переносимо, чем использование диапазонов символов на разных платформах и языках. Например, [0-9] соответствует цифре в западных алфавитах, а \d соответствует цифре в любом алфавите. Замечание: В другой документации по регулярным выражениям наборы символов часто называют "классами символов". Кванторы По умолчанию выражение автоматически определяется {1,1}, т.е. оно должно произойти точно один раз. В следующем списке 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 обозначает выражение.
Соответствие подстановочных знаков Большинство командных оболочек, таких как bash или cmd.exe, поддерживают "подстановку файлов", возможность идентифицировать группу файлов при помощи подстановочных знаков. Функция setPatternSyntax () используется для переключения между регулярными выражениями и режимом подстановочных знаков. Соответствие подстановочных знаков более простое, чем полные регулярные выражения, и имеет только четыре возможности:
В режиме 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;)"); // соответствует амперсанду, но не & 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"); // соответствие 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" . Перечисление CaretMode определяет различные значения каретки (^) в регулярном выражении. Возможные значения:
Синтаксис используется для интерпретации значений шаблона.
Смотрите также setPatternSyntax (). Создаёт пустое регулярное выражение. Смотрите также 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. Уничтожает регулярное выражение и очищает внутренние данные. Q String 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. Q StringList 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 (). Q t::CaseSensitivity QRegExp::caseSensitivity () const Возвращает Qt::CaseSensitive , если регулярное выражение сравнивается с учётом регистра; в противном случае возвращает Qt::CaseInsensitive . Смотрите также setCaseSensitivity (), patternSyntax (), pattern () и isMinimal (). Q String QRegExp::errorString () const Возвращает текстовую строку, которая объясняет, почему шаблон регулярного выражения неверен в случае наличия в нём ошибки; в противном случае возвращает "no error occurred". Q String 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. 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 (). Q String QRegExp::pattern () const Возвращает строку шаблона регулярного выражения. Шаблон имеет синтаксис либо регулярного выражения, либо подстановочных знаков, в зависимости от patternSyntax (). Смотрите также setPattern (), patternSyntax () и caseSensitivity (). P atternSyntax 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. QRegExp & QRegExp::operator= ( const QRegExp & rx ) Копирует регулярное выражение rx и возвращает ссылку на копию. Опции учёта регистра, подстановочных знаков и минимального соответствия также копируются. bool QRegExp::operator== ( const QRegExp & rx ) const Возвращает true, если регулярное выражение равно rx; в противном случае возвращает false. Два объекта QRegExp равны, если они имеют одинаковую строку шаблона и одинаковые настройки учёта регистра, подстановочных знаков и минимального соответствия. Связанные нечлены класса Q DataStream & operator<< ( QDataStream & out, const QRegExp & regExp ) Записывает регулярное выражение regExp в поток out. Смотрите также Формат операторов QDataStream . Q DataStream & operator>> ( QDataStream & in, QRegExp & regExp ) Читает регулярное выражение из потока in в regExp. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Так же в этом разделе:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|