Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Understanding Marked Sub-Expressions and Captures

Boost , Boost.Regex 5.1.2 , Boost.Regex 5.1.2

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Захваты — это диапазоны итераторов, которые «захватываются» помеченными суб-выражениями, когда обычное выражение совпадает. Каждая отмеченная субэкспрессия может привести к более чем одному захвату, если она совпадает более одного раза. В этом документе объясняется, как фиксируются и отмечаются суб-выражения в Boost. Regex представлен и доступен.

Marked sub-expressions

Каждый раз, когда регулярное выражение Perl содержит группу скобок (), оно выделяет дополнительное поле, известное как отмеченное подвыражение, например выражение:

(\w+)\W+(\w+)

Имеет два отмеченных суб-выражения (известные как $1 и $2 соответственно), кроме того, полный матч известен как $&, все до первого матча как $, и все после матча как $. Таким образом, если вышеуказанное выражение ищется в "@abc def--", то мы получаем:

Подвыражение

Текст найден

$

"@"

$&

"abc def"

$1

"abc"

$2

"def"

$

"--"

В Росте. Все они доступны через класс match_results, который заполняется при вызове одного из алгоритмов соответствия регулярных выражений (regex_search, regex_match или regex_iterator). Так дано:

boost::match_results<IteratorType> m;

Перл и буст. Эквивалентами Regex являются:

Перл

Повышаю. Регей

$

m.prefix()

$&

m[0

$n

m[n

$

m. суффикс ()

В Росте. Каждый подэкспрессионный матч представлен объектом sub_match, это в основном просто пара итераторов, обозначающих начальное и конечное положение подэкспрессионного матча, но есть некоторые дополнительные операторы, предоставленные таким образом, что объекты типа sub_match ведут себя очень похоже на std::basic_string: например, они неявно конвертируемы в basic_string, их можно сравнить со строкой, добавить к строке или выпустить на выходной поток.

Unmatched Sub-Expressions

При обнаружении регулярного совпадения выражений нет необходимости в том, чтобы все отмеченные субвыражения участвовали в матче, например, выражение:

(abc)|(def)

это может быть как $1, так и $2, но не одновременно. В Росте. Regex можно определить, какие подэкспрессии совпадают, получив доступ к sub_match::matched элементу данных.

Repeated Captures

Когда отмеченное подвыражение повторяется, то подвыражение «захватывается» несколько раз, однако обычно доступен только окончательный захват, например, если

(?:(\w+)\W+)+

противопоставляется

one fine day

Тогда $1 будет содержать строку "день", а все предыдущие захваты будут забыты.

Тем не менее, буст. Regex имеет экспериментальную функцию, которая позволяет сохранить всю информацию о захвате - к ней можно получить доступ либо через функцию члена match_results::captures, либо через функцию члена sub_match::captures. Эти функции возвращают контейнер, который содержит последовательность всех захватов, полученных во время согласования регулярных выражений. Следующий пример программы показывает, как эта информация может быть использована:

#include <boost/regex.hpp>
#include <iostream>
void print_captures(const std::string& regx, const std::string& text)
{
   boost::regex e(regx);
   boost::smatch what;
   std::cout << "Expression:  \"" << regx << "\"\n";
   std::cout << "Text:        \"" << text << "\"\n";
   if(boost::regex_match(text, what, e, boost::match_extra))
   {
      unsigned i, j;
      std::cout << "** Match found **\n   Sub-Expressions:\n";
      for(i = 0; i < what.size(); ++i)
         std::cout << "      $" << i << " = \"" << what[i] << "\"\n";
      std::cout << "   Captures:\n";
      for(i = 0; i < what.size(); ++i)
      {
         std::cout << "      $" << i << " = {";
         for(j = 0; j < what.captures(i).size(); ++j)
         {
            if(j)
               std::cout << ", ";
            else
               std::cout << " ";
            std::cout << "\"" << what.captures(i)[j] << "\"";
         }
         std::cout << " }\n";
      }
   }
   else
   {
      std::cout << "** No Match found **\n";
   }
}
int main(int , char* [])
{
   print_captures("(([[:lower:]]+)|([[:upper:]]+))+", "aBBcccDDDDDeeeeeeee");
   print_captures("(.*)bar|(.*)bah", "abcbar");
   print_captures("(.*)bar|(.*)bah", "abcbah");
   print_captures("^(?:(\\w+)|(?>\\W+))*$",
      "now is the time for all good men to come to the aid of the party");
   return 0;
}

Который производит следующую продукцию:

Expression:  "(([[:lower:]]+)|([[:upper:]]+))+"
Text:        "aBBcccDDDDDeeeeeeee"
** Match found **
   Sub-Expressions:
      $0 = "aBBcccDDDDDeeeeeeee"
      $1 = "eeeeeeee"
      $2 = "eeeeeeee"
      $3 = "DDDDD"
   Captures:
      $0 = { "aBBcccDDDDDeeeeeeee" }
      $1 = { "a", "BB", "ccc", "DDDDD", "eeeeeeee" }
      $2 = { "a", "ccc", "eeeeeeee" }
      $3 = { "BB", "DDDDD" }
Expression:  "(.*)bar|(.*)bah"
Text:        "abcbar"
** Match found **
   Sub-Expressions:
      $0 = "abcbar"
      $1 = "abc"
      $2 = ""
   Captures:
      $0 = { "abcbar" }
      $1 = { "abc" }
      $2 = { }
Expression:  "(.*)bar|(.*)bah"
Text:        "abcbah"
** Match found **
   Sub-Expressions:
      $0 = "abcbah"
      $1 = ""
      $2 = "abc"
   Captures:
      $0 = { "abcbah" }
      $1 = { }
      $2 = { "abc" }
Expression:  "^(?:(\w+)|(?>\W+))*$"
Text:        "now is the time for all good men to come to the aid of the party"
** Match found **
   Sub-Expressions:
      $0 = "now is the time for all good men to come to the aid of the party"
      $1 = "party"
   Captures:
      $0 = { "now is the time for all good men to come to the aid of the party" }
      $1 = { "now", "is", "the", "time", "for", "all", "good", "men", "to",
         "come", "to", "the", "aid", "of", "the", "party" }

К сожалению, включение этой функции влияет на производительность (даже если вы не используете ее), и гораздо большее влияние, если вы используете ее, поэтому для использования этой функции вам нужно:

  • Определите BOOST_REGEX_MATCH_EXTRA для всех блоков перевода, включая источник библиотеки (лучший способ сделать это - откомментировать это определение в boost/regex/user.hpp, а затем перестроить все).
  • Передайте флаг match_extra конкретным алгоритмам, в которых вам действительно нужна информация о захвате (regex_search, regex_match или regex_iterator).

PrevUpHomeNext

Статья Understanding Marked Sub-Expressions and Captures раздела Boost.Regex 5.1.2 Boost.Regex 5.1.2 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Boost.Regex 5.1.2 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:11:33/0.0047399997711182/0