Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Examples

Below you can find six complete sample programs.

See if a whole string matches a regex

This is the example from the Introduction. It is reproduced here for your convenience.

#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    std::string hello( "hello world!" );

    sregex rex = sregex::compile( "(\\w+) (\\w+)!" );
    smatch what;

    if( regex_match( hello, what, rex ) )
    {
        std::cout << what[0] << '\n'; // whole match
        std::cout << what[1] << '\n'; // first capture
        std::cout << what[2] << '\n'; // second capture
    }

    return 0;
}

This program outputs the following:

hello world!
hello
world


top

See if a string contains a sub-string that matches a regex

Notice in this example how we use custom mark_tags to make the pattern more readable. We can use the mark_tags later to index into the match_results<>.

#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    char const *str = "I was born on 5/30/1973 at 7am.";

    // define some custom mark_tags with names more meaningful than s1, s2, etc.
    mark_tag day(1), month(2), year(3), delim(4);

    // this regex finds a date
    cregex date = (month= repeat<1,2>(_d))           // find the month ...
               >> (delim= (set= '/','-'))            // followed by a delimiter ...
               >> (day=   repeat<1,2>(_d)) >> delim  // and a day followed by the same delimiter ...
               >> (year=  repeat<1,2>(_d >> _d));    // and the year.

    cmatch what;

    if( regex_search( str, what, date ) )
    {
        std::cout << what[0]     << '\n'; // whole match
        std::cout << what[day]   << '\n'; // the day
        std::cout << what[month] << '\n'; // the month
        std::cout << what[year]  << '\n'; // the year
        std::cout << what[delim] << '\n'; // the delimiter
    }

    return 0;
}

This program outputs the following:

5/30/1973
30
5
1973
/


top

Replace all sub-strings that match a regex

The following program finds dates in a string and marks them up with pseudo-HTML.

#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    std::string str( "I was born on 5/30/1973 at 7am." );

    // essentially the same regex as in the previous example, but using a dynamic regex
    sregex date = sregex::compile( "(\\d{1,2})([/-])(\\d{1,2})\\2((?:\\d{2}){1,2})" );

    // As in Perl, $& is a reference to the sub-string that matched the regex
    std::string format( "<date>$&</date>" );

    str = regex_replace( str, date, format );
    std::cout << str << '\n';

    return 0;
}

This program outputs the following:

I was born on <date>5/30/1973</date> at 7am.


top

Find all the sub-strings that match a regex and step through them one at a time

The following program finds the words in a wide-character string. It uses wsregex_iterator. Notice that dereferencing a wsregex_iterator yields a wsmatch object.

#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    std::wstring str( L"This is his face." );

    // find a whole word
    wsregex token = +alnum;

    wsregex_iterator cur( str.begin(), str.end(), token );
    wsregex_iterator end;

    for( ; cur != end; ++cur )
    {
        wsmatch const &what = *cur;
        std::wcout << what[0] << L'\n';
    }

    return 0;
}

This program outputs the following:

This
is
his
face


top

Split a string into tokens that each match a regex

The following program finds race times in a string and displays first the minutes and then the seconds. It uses regex_token_iterator<>.

#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    std::string str( "Eric: 4:40, Karl: 3:35, Francesca: 2:32" );

    // find a race time
    sregex time = sregex::compile( "(\\d):(\\d\\d)" );

    // for each match, the token iterator should first take the value of
    // the first marked sub-expression followed by the value of the second
    // marked sub-expression
    int const subs[] = { 1, 2 };

    sregex_token_iterator cur( str.begin(), str.end(), time, subs );
    sregex_token_iterator end;

    for( ; cur != end; ++cur )
    {
        std::cout << *cur << '\n';
    }

    return 0;
}

This program outputs the following:

4
40
3
35
2
32


top

Split a string using a regex as a delimiter

The following program takes some text that has been marked up with html and strips out the mark-up. It uses a regex that matches an HTML tag and a regex_token_iterator<> that returns the parts of the string that do not match the regex.

#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    std::string str( "Now <bold>is the time <i>for all good men</i> to come to the aid of their</bold> country." );

    // find a HTML tag
    sregex html = '<' >> optional('/') >> +_w >> '>';

    // the -1 below directs the token iterator to display the parts of
    // the string that did NOT match the regular expression.
    sregex_token_iterator cur( str.begin(), str.end(), html, -1 );
    sregex_token_iterator end;

    for( ; cur != end; ++cur )
    {
        std::cout << '{' << *cur << '}';
    }
    std::cout << '\n';

    return 0;
}

This program outputs the following:

{Now }{is the time }{for all good men}{ to come to the aid of their}{ country.}


top

Display a tree of nested results

Here is a helper class to demonstrate how you might display a tree of nested results:

// Displays nested results to std::cout with indenting
struct output_nested_results
{
    int tabs_;

    output_nested_results( int tabs = 0 )
        : tabs_( tabs )
    {
    }

    template< typename BidiIterT >
    void operator ()( match_results< BidiIterT > const &what ) const
    {
        // first, do some indenting
        typedef typename std::iterator_traits< BidiIterT >::value_type char_type;
        char_type space_ch = char_type(' ');
        std::fill_n( std::ostream_iterator<char_type>( std::cout ), tabs_ * 4, space_ch );

        // output the match
        std::cout << what[0] << '\n';

        // output any nested matches
        std::for_each(
            what.nested_results().begin(),
            what.nested_results().end(),
            output_nested_results( tabs_ + 1 ) );
    }
};

top


PrevUpHomeNext