Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57395 - in trunk: boost/xpressive libs/xpressive/doc
From: eric_at_[hidden]
Date: 2009-11-04 19:58:29


Author: eric_niebler
Date: 2009-11-04 19:58:28 EST (Wed, 04 Nov 2009)
New Revision: 57395
URL: http://svn.boost.org/trac/boost/changeset/57395

Log:
document named captures
Added:
   trunk/libs/xpressive/doc/named_captures.qbk (contents, props changed)
Text files modified:
   trunk/boost/xpressive/regex_algorithms.hpp | 6 +++---
   trunk/libs/xpressive/doc/static_regexes.qbk | 1 -
   trunk/libs/xpressive/doc/xpressive.qbk | 3 +++
   3 files changed, 6 insertions(+), 4 deletions(-)

Modified: trunk/boost/xpressive/regex_algorithms.hpp
==============================================================================
--- trunk/boost/xpressive/regex_algorithms.hpp (original)
+++ trunk/boost/xpressive/regex_algorithms.hpp 2009-11-04 19:58:28 EST (Wed, 04 Nov 2009)
@@ -95,7 +95,7 @@
 /// \param flags Optional match flags, used to control how the expression is matched
 /// against the sequence. (See \c match_flag_type.)
 /// \return \c true if a match is found, \c false otherwise
-/// \throw \c regex_error on stack exhaustion
+/// \throw regex_error on stack exhaustion
 template<typename BidiIter>
 inline bool regex_match
 (
@@ -417,7 +417,7 @@
 /// \param flags Optional match flags, used to control how the expression is matched against
 /// the sequence. (See \c match_flag_type.)
 /// \return \c true if a match is found, \c false otherwise
-/// \throw \c regex_error on stack exhaustion
+/// \throw regex_error on stack exhaustion
 template<typename BidiIter>
 inline bool regex_search
 (
@@ -746,7 +746,7 @@
 /// \param flags Optional match flags, used to control how the expression is matched against
 /// the sequence. (See \c match_flag_type.)
 /// \return The value of the output iterator after the output sequence has been written to it.
-/// \throw \c regex_error on stack exhaustion or invalid format string.
+/// \throw regex_error on stack exhaustion or invalid format string.
 template<typename OutIter, typename BidiIter, typename Formatter>
 inline OutIter regex_replace
 (

Added: trunk/libs/xpressive/doc/named_captures.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/xpressive/doc/named_captures.qbk 2009-11-04 19:58:28 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,120 @@
+[/
+ / Copyright (c) 2009 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Named Captures]
+
+[h2 Overview]
+
+For complicated regular expressions, dealing with numbered captures can be a
+pain. Counting left parentheses to figure out which capture to reference is
+no fun. Less fun is the fact that merely editing a regular expression could
+cause a capture to be assigned a new number, invaliding code that refers back
+to it by the old number.
+
+Other regular expression engines solve this problem with a feature called
+/named captures/. This feature allows you to assign a name to a capture, and
+to refer back to the capture by name rather by number. Xpressive also supports
+named captures, both in dynamic and in static regexes.
+
+[h2 Dynamic Named Captures]
+
+For dynamic regular expressions, xpressive follows the lead of other popular
+regex engines with the syntax of named captures. You can create a named capture
+with `"(?P<xxx>...)"` and refer back to that capture with `"(?P=xxx)"`. Here,
+for instance, is a regular expression that creates a named capture and refers
+back to it:
+
+ // Create a named capture called "char" that matches a single
+ // character and refer back to that capture by name.
+ sregex rx = sregex::compile("(?P<char>.)(?P=char)");
+
+The effect of the above regular expression is to find the first doubled
+character.
+
+Once you have executed a match or search operation using a regex with named
+captures, you can access the named capture through the _match_results_ object
+using the capture's name.
+
+ std::string str("tweet");
+ sregex rx = sregex::compile("(?P<char>.)(?P=char)");
+ smatch what;
+ if(regex_search(str, what, rx))
+ {
+ std::cout << "char = " << what["char"] << std::endl;
+ }
+
+The above code displays:
+
+[pre
+char = e
+]
+
+You can also refer back to a named capture from within a substitution string.
+The syntax for that is `"\\g<xxx>"`. Below is some code that demonstrates how
+to use named captures when doing string substitution.
+
+ std::string str("tweet");
+ sregex rx = sregex::compile("(?P<char>.)(?P=char)");
+ str = regex_replace(str, rx, "**\\g<char>**", regex_constants::format_perl);
+ std::cout << str << std::endl;
+
+Notice that you have to specify `format_perl` when using named captures. Only
+the perl syntax recognizes the `"\\g<xxx>"` syntax. The above code displays:
+
+[pre
+tw\*\*e\*\*t
+]
+
+[h2 Static Named Captures]
+
+If you're using static regular expressions, creating and using named
+captures is even easier. You can use the _mark_tag_ type to create
+a variable that you can use like [globalref boost::xpressive::s1 `s1`],
+[globalref boost::xpressive::s1 `s2`] and friends, but with a name
+that is more meaningful. Below is how the above example would look
+using static regexes:
+
+ mark_tag char_(1); // char_ is now a synonym for s1
+ sregex rx = (char_= _) >> char_;
+
+After a match operation, you can use the `mark_tag` to index into the
+_match_results_ to access the named capture:
+
+ std::string str("tweet");
+ mark_tag char_(1);
+ sregex rx = (char_= _) >> char_;
+ smatch what;
+ if(regex_search(str, what, rx))
+ {
+ std::cout << what[char_] << std::endl;
+ }
+
+The above code displays:
+
+[pre
+char = e
+]
+
+When doing string substitutions with _regex_replace_, you can use named
+captures to create /format expressions/ as below:
+
+ std::string str("tweet");
+ mark_tag char_(1);
+ sregex rx = (char_= _) >> char_;
+ str = regex_replace(str, rx, "**" + char_ + "**");
+ std::cout << str << std::endl;
+
+The above code displays:
+
+[pre
+tw\*\*e\*\*t
+]
+
+[note You need to include [^<boost/xpressive/regex_actions.hpp>] to
+use format expressions.]
+
+[endsect]

Modified: trunk/libs/xpressive/doc/static_regexes.qbk
==============================================================================
--- trunk/libs/xpressive/doc/static_regexes.qbk (original)
+++ trunk/libs/xpressive/doc/static_regexes.qbk 2009-11-04 19:58:28 EST (Wed, 04 Nov 2009)
@@ -169,7 +169,6 @@
 [def _before_ [funcref boost::xpressive::before before]]
 [def _after_ [funcref boost::xpressive::after after]]
 [def _keep_ [funcref boost::xpressive::keep keep]]
-[def _mark_tag_ [classref boost::xpressive::mark_tag mark_tag]]
 
 [table Perl syntax vs. Static xpressive syntax
     [[Perl] [Static xpressive] [Meaning]]

Modified: trunk/libs/xpressive/doc/xpressive.qbk
==============================================================================
--- trunk/libs/xpressive/doc/xpressive.qbk (original)
+++ trunk/libs/xpressive/doc/xpressive.qbk 2009-11-04 19:58:28 EST (Wed, 04 Nov 2009)
@@ -49,6 +49,7 @@
 [def _regex_compiler_ [^[classref boost::xpressive::regex_compiler regex_compiler<>]]]
 [def _regex_iterator_ [^[classref boost::xpressive::regex_iterator regex_iterator<>]]]
 [def _regex_token_iterator_ [^[classref boost::xpressive::regex_token_iterator regex_token_iterator<>]]]
+[def _mark_tag_ [^[classref boost::xpressive::mark_tag mark_tag]]]
 [def _regex_match_ [^[funcref boost::xpressive::regex_match regex_match()]]]
 [def _regex_search_ [^[funcref boost::xpressive::regex_search regex_search()]]]
 [def _regex_replace_ [^[funcref boost::xpressive::regex_replace regex_replace()]]]
@@ -92,6 +93,8 @@
 
 [include tokenization.qbk]
 
+[include named_captures.qbk]
+
 [include grammars.qbk]
 
 [include actions.qbk]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk