2015-05-21 3 views
1

Я чувствую, что это довольно простой вопрос, но я не нашел для него сообщения. Если вы знаете, пожалуйста, напишите ниже. Так что я пытаюсь сделать, это посмотреть через строку и извлечь числа в группах 2.Поиск числа между двумя номерами с использованием regex/boost в C++

вот мой код:

int main() { 
     string line = "P112233"; 
     boost::regex e ("P([0-9]{2}[0-9]{2}[0-9]{2})"); 
     boost::smatch match; 

     if (boost::regex_search(line, match, e)) 
     { 
      boost::regex f("([0-9]{2})"); //finds 11 
      boost::smatch match2; 
      line = match[0]; 
      if (boost::regex_search(line, match2, f)) 
      { 
       float number1 = boost::lexical_cast<float>(match2[0]); 
       cout << number1 << endl; // this works and prints out 11. 
      } 

      boost::regex g("   "); // here I want it to find the 22 
      boost::smatch match3; 
      if (boost::regex_search(line, match3, g)) 
      { 
       float number2 = boost::lexical_cast<float>(match3[0]); 
       cout << number2 << endl; 
      } 
      boost::regex h("   "); // here I want it to find the 33 
      boost::smatch match4; 
      if (boost::regex_search(line, match4, h)) 
      { 
       float number3 = boost::lexical_cast<float>(match4[0]); 
       cout << number3 << endl; 
      } 
     } 
     else 
      cout << "found nothing"<< endl; 
    return 0; 
} 

Я был в состоянии получить первый номер, но у меня есть не знаю, как получить второй (22) и третий (33). Какое правильное выражение мне нужно использовать?

+0

Если вы используете 3 группы захвата (т.е. '" P ([0-9] {2}) ([0-9] {2}) ([0- 9] {2}) "'), тогда вы можете просто получить доступ к 'match [i]', где 'i' - номер группы, которую вы хотите извлечь (я считаю, что' match [0] '- вся строка, , – Cornstalks

+0

Да, совпадение [0] - вся строка. Кажется, я понимаю, что вы имеете в виду, но я никогда раньше не использовал группы захвата. матч [1, 2, 3 и т. д.] не имеют ничего. Я продолжаю получать эту ошибку 'terminate called после того, как вы выбрали экземпляр 'boost :: exception_detail :: clone_impl >' what(): bad lexical cast: значение типа источника может не следует интерпретировать как цель , можете ли вы дать мне дополнительную информацию? – KH17

ответ

2

Как @Cornstalks упоминался вам необходимо использовать 3 захват групп, а затем доступ к ним так:

int main() 
{ 
    std::string line = "P112233"; 
    boost::regex e("P([0-9]{2})([0-9]{2})([0-9]{2})"); 
    boost::smatch match; 

    if (boost::regex_search(line, match, e)) 
    { 
     std::cout << match[0] << std::endl; // prints the whole string 
     std::cout << match[1] << ", " << match[2] << ", " << match[3] << std::endl; 
    } 

    return 0; 
} 

Выходные:

P112233 
11, 22, 33 
+0

Отлично! Большое спасибо! Можете ли вы рассказать мне, для чего нужны первая и вторая. – KH17

+0

@ KH17. First и .second - итераторы, указывающие на начало и конец строки. – doqtor

+1

@doqtor В этом нет необходимости: ['str()' проще) (http://coliru.stacked-crooked.com/a/42c90f35586cadfa), или действительно [используйте неявное преобразование] (http: // coliru .stacked-crooked.com/a/75460f293028fd2b) или действительно зачем назначать [вообще] (http://coliru.stacked-crooked.com/a/85c86182d671adf). Но опять же, я бы не использовал regex здесь. См. * [Мой ответ] (http://stackoverflow.com/a/30385086/85371) * – sehe

1

Я не жалую регулярные выражения для этого вида разбор. Ключевым моментом является то, что числа по-прежнему являются строками, когда вы закончите этот эпизод с волосатым регулярным выражением.

Вместо этого я использовал бы Boost Spirit здесь, который анализирует числа сразу, и вам даже не нужно ссылаться на библиотеку Regex Boost, потому что Spirit - только заголовок.

Live On Coliru

#include <boost/spirit/include/qi.hpp> 
#include <iostream> 

namespace qi = boost::spirit::qi; 
static qi::int_parser<int, 10, 2, 2> two_digits; 

int main() { 
    std::string const s = "P112233"; 

    std::vector<int> nums; 
    if (qi::parse(s.begin(), s.end(), "P" >> *two_digits, nums)) 
    { 
     std::cout << "Parsed " << nums.size() << " pairs of digits:\n"; 
     for(auto i : nums) 
      std::cout << " * " << i << "\n"; 
    } 
} 


Parsed 3 pairs of digits: 
* 11 
* 22 
* 33 
Смежные вопросы