f11333d352
[SVN r40900]
321 lines
11 KiB
Plaintext
321 lines
11 KiB
Plaintext
[/
|
|
Copyright 2006-2007 John Maddock.
|
|
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:regex_grep regex_grep (Deprecated)]
|
|
|
|
The algorithm `regex_grep` is deprecated in favor of [regex_iterator]
|
|
which provides a more convenient and standard library friendly interface.
|
|
|
|
The following documentation is taken unchanged from the previous boost
|
|
release, and will not be updated in future.
|
|
|
|
#include <boost/regex.hpp>
|
|
|
|
`regex_grep` allows you to search through a bidirectional-iterator range and
|
|
locate all the (non-overlapping) matches with a given regular expression.
|
|
The function is declared as:
|
|
|
|
template <class Predicate, class iterator, class charT, class traits>
|
|
unsigned int regex_grep(Predicate foo,
|
|
iterator first,
|
|
iterator last,
|
|
const basic_regex<charT, traits>& e,
|
|
boost::match_flag_type flags = match_default)
|
|
|
|
The library also defines the following convenience versions, which take
|
|
either a `const charT*`, or a `const std::basic_string<>&` in place of a
|
|
pair of iterators.
|
|
|
|
template <class Predicate, class charT, class traits>
|
|
unsigned int regex_grep(Predicate foo,
|
|
const charT* str,
|
|
const basic_regex<charT, traits>& e,
|
|
boost::match_flag_type flags = match_default);
|
|
|
|
template <class Predicate, class ST, class SA, class charT, class traits>
|
|
unsigned int regex_grep(Predicate foo,
|
|
const std::basic_string<charT, ST, SA>& s,
|
|
const basic_regex<charT, traits>& e,
|
|
boost::match_flag_type flags = match_default);
|
|
|
|
The parameters for the primary version of `regex_grep` have the following meanings:
|
|
|
|
foo: A predicate function object or function pointer, see below for more information.
|
|
|
|
first: The start of the range to search.
|
|
|
|
last: The end of the range to search.
|
|
|
|
e: The regular expression to search for.
|
|
|
|
flags: The flags that determine how matching is carried out, one of the match_flags enumerators.
|
|
|
|
|
|
The algorithm finds all of the non-overlapping matches of the expression /e/,
|
|
for each match it fills a `match_results<iterator>` structure, which
|
|
contains information on what matched, and calls the predicate /foo/, passing the
|
|
`match_results<iterator>` as a single argument. If the predicate returns
|
|
/true/, then the grep operation continues, otherwise it terminates
|
|
without searching for further matches. The function returns the number
|
|
of matches found.
|
|
|
|
The general form of the predicate is:
|
|
|
|
struct grep_predicate
|
|
{
|
|
bool operator()(const match_results<iterator_type>& m);
|
|
};
|
|
|
|
For example the regular expression "a\*b" would find one match in the string
|
|
"aaaaab" and two in the string "aaabb".
|
|
|
|
Remember this algorithm can be used for a lot more than implementing a
|
|
version of grep, the predicate can be and do anything that you want,
|
|
grep utilities would output the results to the screen, another program could
|
|
index a file based on a regular expression and store a set of bookmarks in a list,
|
|
or a text file conversion utility would output to file. The results of one
|
|
`regex_grep` can even be chained into another `regex_grep` to create recursive parsers.
|
|
|
|
The algorithm may throw `std::runtime_error` if the complexity of matching the
|
|
expression against an /N/ character string begins to exceed O(N[super 2]), or
|
|
if the program runs out of stack space while matching the expression
|
|
(if Boost.Regex is configured in recursive mode), or if the matcher
|
|
exhausts it's permitted memory allocation (if Boost.Regex is configured in
|
|
non-recursive mode).
|
|
|
|
Example: convert the example from [regex_search] to use `regex_grep` instead:
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <boost/regex.hpp>
|
|
|
|
// IndexClasses:
|
|
// takes the contents of a file in the form of a string
|
|
// and searches for all the C++ class definitions, storing
|
|
// their locations in a map of strings/int's
|
|
typedef std::map<std::string, int, std::less<std::string> > map_type;
|
|
|
|
const char* re =
|
|
// possibly leading whitespace:
|
|
"^[[:space:]]*"
|
|
// possible template declaration:
|
|
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
|
// class or struct:
|
|
"(class|struct)[[:space:]]*"
|
|
// leading declspec macros etc:
|
|
"("
|
|
"\\<\\w+\\>"
|
|
"("
|
|
"[[:blank:]]*\\([^)]*\\)"
|
|
")?"
|
|
"[[:space:]]*"
|
|
")*"
|
|
// the class name
|
|
"(\\<\\w*\\>)[[:space:]]*"
|
|
// template specialisation parameters
|
|
"(<[^;:{]+>)?[[:space:]]*"
|
|
// terminate in { or :
|
|
"(\\{|:[^;\\{()]*\\{)";
|
|
|
|
boost::regex expression(re);
|
|
class IndexClassesPred
|
|
{
|
|
map_type& m;
|
|
std::string::const_iterator base;
|
|
public:
|
|
IndexClassesPred(map_type& a, std::string::const_iterator b) : m(a), base(b) {}
|
|
bool operator()(const smatch& what)
|
|
{
|
|
// what[0] contains the whole string
|
|
// what[5] contains the class name.
|
|
// what[6] contains the template specialisation if any.
|
|
// add class name and position to map:
|
|
m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
|
|
what[5].first - base;
|
|
return true;
|
|
}
|
|
};
|
|
void IndexClasses(map_type& m, const std::string& file)
|
|
{
|
|
std::string::const_iterator start, end;
|
|
start = file.begin();
|
|
end = file.end();
|
|
regex_grep(IndexClassesPred(m, start), start, end, expression);
|
|
}
|
|
|
|
Example: Use `regex_grep` to call a global callback function:
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <boost/regex.hpp>
|
|
|
|
// purpose:
|
|
// takes the contents of a file in the form of a string
|
|
// and searches for all the C++ class definitions, storing
|
|
// their locations in a map of strings/int's
|
|
typedef std::map<std::string, int, std::less<std::string> > map_type;
|
|
|
|
const char* re =
|
|
// possibly leading whitespace:
|
|
"^[[:space:]]*"
|
|
// possible template declaration:
|
|
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
|
// class or struct:
|
|
"(class|struct)[[:space:]]*"
|
|
// leading declspec macros etc:
|
|
"("
|
|
"\\<\\w+\\>"
|
|
"("
|
|
"[[:blank:]]*\\([^)]*\\)"
|
|
")?"
|
|
"[[:space:]]*"
|
|
")*"
|
|
// the class name
|
|
"(\\<\\w*\\>)[[:space:]]*"
|
|
// template specialisation parameters
|
|
"(<[^;:{]+>)?[[:space:]]*"
|
|
// terminate in { or :
|
|
"(\\{|:[^;\\{()]*\\{)";
|
|
|
|
boost::regex expression(re);
|
|
map_type class_index;
|
|
std::string::const_iterator base;
|
|
|
|
bool grep_callback(const boost::smatch& what)
|
|
{
|
|
// what[0] contains the whole string
|
|
// what[5] contains the class name.
|
|
// what[6] contains the template specialisation if any.
|
|
// add class name and position to map:
|
|
class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
|
|
what[5].first - base;
|
|
return true;
|
|
}
|
|
void IndexClasses(const std::string& file)
|
|
{
|
|
std::string::const_iterator start, end;
|
|
start = file.begin();
|
|
end = file.end();
|
|
base = start;
|
|
regex_grep(grep_callback, start, end, expression, match_default);
|
|
}
|
|
|
|
|
|
Example: use `regex_grep` to call a class member function, use the standard
|
|
library adapters `std::mem_fun` and `std::bind1st` to convert the member
|
|
function into a predicate:
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <boost/regex.hpp>
|
|
#include <functional>
|
|
// purpose:
|
|
// takes the contents of a file in the form of a string
|
|
// and searches for all the C++ class definitions, storing
|
|
// their locations in a map of strings/int's
|
|
|
|
typedef std::map<std::string, int, std::less<std::string> > map_type;
|
|
class class_index
|
|
{
|
|
boost::regex expression;
|
|
map_type index;
|
|
std::string::const_iterator base;
|
|
bool grep_callback(boost::smatch what);
|
|
public:
|
|
void IndexClasses(const std::string& file);
|
|
class_index()
|
|
: index(),
|
|
expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
|
"(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?"
|
|
"[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?"
|
|
"(\\{|:[^;\\{()]*\\{)"
|
|
){}
|
|
};
|
|
bool class_index::grep_callback(boost::smatch what)
|
|
{
|
|
// what[0] contains the whole string
|
|
// what[5] contains the class name.
|
|
// what[6] contains the template specialisation if any.
|
|
// add class name and position to map:
|
|
index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
|
|
what[5].first - base;
|
|
return true;
|
|
}
|
|
|
|
void class_index::IndexClasses(const std::string& file)
|
|
{
|
|
std::string::const_iterator start, end;
|
|
start = file.begin();
|
|
end = file.end();
|
|
base = start;
|
|
regex_grep(std::bind1st(std::mem_fun(&class_index::grep_callback), this),
|
|
start,
|
|
end,
|
|
expression);
|
|
}
|
|
|
|
|
|
Finally, C++ Builder users can use C++ Builder's closure type as a callback argument:
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <boost/regex.hpp>
|
|
#include <functional>
|
|
// purpose:
|
|
// takes the contents of a file in the form of a string
|
|
// and searches for all the C++ class definitions, storing
|
|
// their locations in a map of strings/int's
|
|
|
|
typedef std::map<std::string, int, std::less<std::string> > map_type;
|
|
class class_index
|
|
{
|
|
boost::regex expression;
|
|
map_type index;
|
|
std::string::const_iterator base;
|
|
typedef boost::smatch arg_type;
|
|
bool grep_callback(const arg_type& what);
|
|
public:
|
|
typedef bool (__closure* grep_callback_type)(const arg_type&);
|
|
void IndexClasses(const std::string& file);
|
|
class_index()
|
|
: index(),
|
|
expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
|
|
"(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?"
|
|
"[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?"
|
|
"(\\{|:[^;\\{()]*\\{)"
|
|
){}
|
|
};
|
|
|
|
bool class_index::grep_callback(const arg_type& what)
|
|
{
|
|
// what[0] contains the whole string
|
|
// what[5] contains the class name.
|
|
// what[6] contains the template specialisation if any.
|
|
// add class name and position to map:
|
|
index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
|
|
what[5].first - base;
|
|
return true;
|
|
}
|
|
|
|
void class_index::IndexClasses(const std::string& file)
|
|
{
|
|
std::string::const_iterator start, end;
|
|
start = file.begin();
|
|
end = file.end();
|
|
base = start;
|
|
class_index::grep_callback_type cl = &(this->grep_callback);
|
|
regex_grep(cl,
|
|
start,
|
|
end,
|
|
expression);
|
|
}
|
|
|
|
|
|
[endsect]
|
|
|