Is C++11 regex ready for prime time?

I've been playing with regex for the first time, and having a great deal of trouble trying to get a simple IPv4 address expression to work. Can anyone see what I am doing wrong here.

::std::regex r( "([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})", ::std::regex::basic );

::std::match_results< const char * > sm;
bool rv = ::std::regex_match( pText, sm, r );
::std::cout << "input string has " << sm.size() << " matches" << ::std::endl;
for (unsigned i=0; i<sm.size(); ++i) {
std::cout << "[" << sm[i] << "] ";
}

If the input is 127.0.0.1, I see
input string has 0 matches
OMG so many ::s...
Looks OK to me. Have you tried the expression in other languages? .Net has a regex class. I think I'll check it via PowerShell.

In the meantime, that can be simplified to ([0-9]{1,3}.){3}[0-9]{1,3} .
Ok, I was having issues with the subgroup in PowerShell and .net. I ended up with the following: (?>[0-9]{1,3}.){3}[0-9]{1,3}

The above matches 127.0.0.1, but not 127.0.0 or shorter ones (it was doing so with the first one I proposed). It should work. At least works in Windows + .Net.

Here's the PowerShell used:

1
2
3
4
5
6
$re = New-Object -TypeName System.Text.RegularExpressions.RegEx -ArgumentList "(?>[0-9]{1,3}.){3}[0-9]{1,3}"
$re.Matches("127.0.0.1") | % { $_.Groups }
Groups   : {127.0.0.1}
Success  : True
Captures : {127.0.0.1}
Index    : 0
Length   : 9
Value    : 127.0.0.1
Btw, I'm seeing this with g++ (Debian 4.7.1-2) 4.7.1. Haven't tried any other compilers yet.
Thanks for the link. Doesn't look too promising. That's a bummer.
In the interim, we can use boost::regex

1
2
3
4
5
6
7
8
#include <string>
#include <boost/regex.hpp>

bool valid_ipv4( const std::string& str )
{
   static const boost::regex re( R"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" ) ;
   return boost::regex_match( str, re ) ;
}


Note: The regex requires modification; 295.7.321.1 is not a valis ipv4 adress in dotted notation; nor is 0.0.0.0.
Regex is ok. Works fine in Scala.

1
2
scala> "([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})".r.findFirstMatchIn("127.0.0.1")
res2: Option[scala.util.matching.Regex.Match] = Some(127.0.0.1)
Last edited on
Boost regex is working great. Thanks all for the help!
Topic archived. No new replies allowed.