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

Partial Matches

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

match_flag_type match_partial может быть передан следующим алгоритмам: regex_match, regex_search, и regex_grep, и используется с итератором regex_iterator>. При его использовании следует найти частичные, а также полные спички. Частичный матч - это тот, который сопоставил один или несколько символов в конце ввода текста, но не соответствовал всем регулярным выражениям (хотя, возможно, это было сделано, если было доступно больше входов). Частичные спички обычно используются при проверке ввода данных (проверке каждого персонажа по мере его ввода на клавиатуре), или при поиске текстов, которые слишком долго загружаются в память (или даже в картированный файл памяти), или имеют неопределенную длину (например, источник может быть розеткой или похожим). Частичные и полные матчи можно дифференцировать, как показано в следующей таблице (переменная M представляет собой экземпляр match_results, заполненный regex_match, regex_search или regex_grep):

Результат

M[0]. Сопоставимый

M[0]. первый

M[0]. вторая

Без матча

Ложь

Неопределенный

Неопределенный

Неопределенный

Частичный матч

Правда

Ложь

Начало частичного матча.

Конец частичного матча (конец текста).

Полный матч

Правда

Правда

Начало полного матча.

Конец полного матча.

Имейте в виду, что использование частичных матчей иногда может привести к несовершенному поведению:

  • Есть некоторые выражения, такие как «.*abc», которые всегда производят частичный матч. Эта проблема может быть уменьшена путем тщательного построения регулярных выражений, используемых, или путем установки флагов, таких как match_not_dot_newline, так что выражения, такие как .*, не могут соответствовать границам прошлых строк.
  • Подъем. Регекс в настоящее время предпочитает левые матчи на полные матчи, поэтому, например, совпадение «abc|b» против «ab» производит частичный матч против «ab», а не полный матч против «b». Это более эффективно работать таким образом, но может быть не то поведение, которое вы хотите во всех ситуациях.
  • Есть ситуации, когда полные матчи встречаются, даже если частичные матчи также возможны: например, если частичная строка заканчивается «abc» и обычное выражение «\w+», то полный матч найден, хотя может быть больше алфавитных символов. Этот конкретный случай может быть обнаружен, проверив, если найденный матч заканчивается в конце текущей строки ввода. Тем не менее, есть ситуации, когда это невозможно: например, выражение, такое как «abc.*123», может всегда иметь более длинные спички, поскольку оно может, как представляется, соответствовать всей строке ввода (независимо от того, как долго это может быть).

Ниже приведен пример тестов, чтобы увидеть, может ли текст быть действительным номером кредитной карты, поскольку пользователь нажимает на ключ, введенный символ будет добавлен к строке, которая строится, и передан is_possible_card_ number. Если это вернет, то текст может быть действительным номером карты, поэтому кнопка OK пользовательского интерфейса будет включена. Если он возвращает ложный, то это еще не действительный номер карты, но может быть с большим вводом, поэтому пользовательский интерфейс отключит кнопку OK. Наконец, если процедура бросает исключение, вход никогда не может стать действительным номером, и введенный символ должен быть отброшен, и соответствующий признак ошибки отображается пользователю.

#include <string>
#include <iostream>
#include <boost/regex.hpp>
boost::regex e("(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})");
bool is_possible_card_number(const std::string& input)
{
   //
   // return false for partial match, true for full match, or throw for
   // impossible match based on what we have so far...
   boost::match_results<std::string::const_iterator> what;
   if(0 == boost::regex_match(input, what, e, boost::match_default | boost::match_partial))
   {
      // the input so far could not possibly be valid so reject it:
      throw std::runtime_error(
         "Invalid data entered - this could not possibly be a valid card number");
   }
   // OK so far so good, but have we finished?
   if(what[0].matched)
   {
      // excellent, we have a result:
      return true;
   }
   // what we have so far is only a partial match...
   return false;
}

В следующем примере текстовый ввод взят из потока, содержащего неизвестное количество текста; этот пример просто учитывает количество тегов HTML, встречающихся в потоке. Текст загружается в буфер и ищет часть за один раз, если был обнаружен частичный матч, то частичный матч проверяется во второй раз как начало следующей партии текста:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <boost/regex.hpp>
// match some kind of html tag:
boost::regex e("<[^>]*>");
// count how many:
unsigned int tags = 0;
void search(std::istream& is)
{
   // buffer we'll be searching in:
   char buf[4096];
   // saved position of end of partial match:
   const char* next_pos = buf + sizeof(buf);
   // flag to indicate whether there is more input to come:
   bool have_more = true;
   while(have_more)
   {
      // how much do we copy forward from last try:
      unsigned leftover = (buf + sizeof(buf)) - next_pos;
      // and how much is left to fill:
      unsigned size = next_pos - buf;
      // copy forward whatever we have left:
      std::memmove(buf, next_pos, leftover);
      // fill the rest from the stream:
      is.read(buf + leftover, size);
      unsigned read = is.gcount();
      // check to see if we've run out of text:
      have_more = read == size;
      // reset next_pos:
      next_pos = buf + sizeof(buf);
      // and then iterate:
      boost::cregex_iterator a(
         buf,
         buf + read + leftover,
         e,
         boost::match_default | boost::match_partial);
      boost::cregex_iterator b;
      while(a != b)
      {
         if((*a)[0].matched == false)
         {
            // Partial match, save position and break:
            next_pos = (*a)[0].first;
            break;
         }
         else
         {
            // full match:
            ++tags;
         }
         // move to next match:
         ++a;
      }
   }
}

Статья Partial Matches раздела 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-07-04 23:45:01/0.0071749687194824/0