简体   繁体   中英

Regular Expression iterator is not working in Cpp

I am working with C++ on Visual Studio 2010 (I don't think its v11 standard but I haven't checked).

I am trying to extract out the IP address of a tracert with the following code:

#include <iomanip>
#include <iostream>
#include <string>
#include <regex>

using namespace std;
typedef regex_iterator<string::iterator> regexp;
#define MAX_BUFFER 255
int main() {
    string out;
    char buffer[MAX_BUFFER];
    smatch m;
    regex e("  1.+\\[(.+)\\]");
    FILE *stream = _popen("tracert SOMEHOSTNAME", "r");
    while ( fgets(buffer, MAX_BUFFER, stream) != NULL ) {
        out = buffer;
        regexp rit (out.begin(), out.end(), e);
        regexp rend;
        while (rit != rend) {
            cout << rit->str() << endl;
            ++rit;
        }
    }
    _pclose(stream);
    cout << "Done.";
    cin >> buffer;
}

however, the regexp is not extracting out the group itself. Instead it is just spitting back the full line!

I thought I was following examples very carefully but it seems I am not using regex_iterator correctly.

1 - How best can I extract the IP from this string

(Side question - is there a C++ function that will go into the network and get the IP from a hostname just like tracert our pint? Another that will get the mac address just like arp -a)

I don't have MSVC, and GNU has broken std::regex support, so I've played with `boost::regex' here:

regex e("^\\s*1\\s.*?\\[(.*?)\\]");

Note this:

  • doesn't assume spaces are spaces rather than tab characters
  • doesn't assume exact spacing at the start of the line
  • does mandate at least 1 space after the 1 character (so it won't match the line starting with 13 , eg)
  • if uses non-greedy matching where possible
#include <iostream>
#include <string>
#include <boost/regex.hpp>

using namespace std;
using boost::regex;
using boost::regex_iterator;
#define MAX_BUFFER 255

int main()
{
    char buffer[MAX_BUFFER];
    regex e("^\\s*1\\s.*?\\[(.*?)\\]");

    FILE *stream = popen("cat input.txt", "r");
    while(fgets(buffer, MAX_BUFFER, stream) != NULL)
    {
        typedef regex_iterator<string::iterator> regit;

        string out = buffer;
        regit rit(out.begin(), out.end(), e);
        regit rend;
        while(rit != rend)
        {
            cout << (*rit)[1].str() << endl;
            ++rit;
        }
    }
    pclose(stream);
    cout << "Done.\n";
}

This appears to work for input.txt :

Tracing route to 11.1.0.1 over a maximum of 30 hops

1     2 ms     3 ms     2 ms  [157.54.48.1]
2    75 ms    83 ms    88 ms  [11.1.0.67]
3    73 ms    79 ms    93 ms  [11.1.0.1]

Trace complete.

printing:

157.54.48.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM