Files
regex/doc/Attic/regex_replace.html
2003-10-21 11:18:40 +00:00

262 lines
17 KiB
HTML
Raw Blame History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Boost.Regex: Algorithm regex_replace</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<LINK href="../../../boost.css" type="text/css" rel="stylesheet"></head>
<body>
<P>
<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="100%" border="0">
<TR>
<td vAlign="top" width="300">
<h3><A href="../../../index.htm"><IMG height="86" alt="C++ Boost" src="../../../c++boost.gif" width="277" border="0"></A></h3>
</td>
<TD width="353">
<H1 align="center">Boost.Regex</H1>
<H2 align="center">Algorithm regex_replace</H2>
</TD>
<td width="50">
<h3><A href="index.html"><IMG height="45" alt="Boost.Regex Index" src="uarrow.gif" width="43" border="0"></A></h3>
</td>
</TR>
</TABLE>
</P>
<HR>
<H3>Contents</H3>
<dl class="index">
<dt><A href="#synopsis">Synopsis</A> <dt><a href="#description">Description</a> <dt><A href="#examples">
Examples</A></dt></dl>
<H3><A name="synopsis"></A>Synopsis</H3>
<PRE>#include &lt;<A href="../../../boost/regex.hpp">boost/regex.hpp</A>&gt; </PRE>
<P>The algorithm regex_replace&nbsp;searches&nbsp;through&nbsp;a string finding
all the matches to the regular expression: for each match it then calls <A href="match_results.html#format">
match_results::format</A> to format the string and sends the result to the
output iterator. Sections of text that do not match are copied to the output
unchanged only if the <EM>flags</EM> parameter does not have the flag <A href="match_flag_type.html">
format_no_copy</A> set. If the flag <A href="match_flag_type.html">format_first_only</A>
is set then only the first occurrence is replaced rather than all
occurrences.&nbsp;<PRE>template &lt;class OutputIterator, class BidirectionalIterator, class traits,
class Allocator, class charT&gt;
OutputIterator <A href="#f1">regex_replace</A>(OutputIterator out,
BidirectionalIterator first,
BidirectionalIterator last,
const <A href="basic_regex.html">basic_regex</A>&lt;charT, traits, Allocator&gt;&amp; e,
const basic_string&lt;charT&gt;&amp; fmt,
<A href="match_flag_type.html">match_flag_type flags = match_default</A>);
template &lt;class traits, class Allocator, class charT&gt;
basic_string&lt;charT&gt; <A href="#f2">regex_replace</A>(const basic_string&lt;charT&gt;&amp; s,
const <A href="basic_regex.html">basic_regex</A>&lt;charT, traits, Allocator&gt;&amp; e,
const basic_string&lt;charT&gt;&amp; fmt,
<A href="match_flag_type.html">match_flag_type flags = match_default</A>);
</PRE>
<H3><A name="description"></A>Description</H3>
<PRE><A name=f1></A>template &lt;class OutputIterator, class BidirectionalIterator, class traits,
class Allocator, class charT&gt;
OutputIterator regex_replace(OutputIterator out,
BidirectionalIterator first,
BidirectionalIterator last,
const <A href="basic_regex.html">basic_regex</A>&lt;charT, traits, Allocator&gt;&amp; e,
const basic_string&lt;charT&gt;&amp; fmt,
<A href="match_flag_type.html">match_flag_type flags = match_default</A>);</PRE>
<P>Enumerates all the occurences of expression <EM>e</EM> in the sequence [first,
last), replacing each occurence with the string that results by merging the
match found with the format string <EM>fmt</EM>, and copies the resulting
string to <EM>out</EM>.&nbsp;</P>
<P>If the flag format_no_copy is set in <EM>flags</EM> then unmatched sections of
text are not copied to output.&nbsp;
</P>
<P>If the flag format_first_only is set in <EM>flags</EM> then only the first
occurence of <EM>e</EM> is replaced.&nbsp;
</P>
<P>The manner in which the format string <EM>fmt</EM> is interpretted, along with
the rules used&nbsp;for finding matches,&nbsp;are determined by the <A href="match_flag_type.html">
flags</A> set in <EM>flags</EM></P>
<P><B>Effects:</B> Constructs an
<SPAN class="spelle">regex_iterator</SPAN>
object:
</P>
<PRE><SPAN style="FONT-SIZE: 10pt">regex_iterator&lt;</SPAN><SPAN class=spelle><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">BidirectionalIterator</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt">, </SPAN><SPAN class=spelle><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">charT</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt">, traits, Allocator&gt; <BR> </SPAN><SPAN class=grame><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">i(</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt">first, last, e, flags)</SPAN>, </PRE>
<P>and uses
<SPAN class="spelle">
<I>i</I></SPAN>
to enumerate through all of the matches <I>m</I> of type
<SPAN class="spelle">
<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">match_results</SPAN>
</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">&lt;<SPAN class="spelle">BidirectionalIterator</SPAN>&gt; </SPAN>that
occur within the sequence [first, last).
</P>
<P>If no such matches are found
<SPAN class="grame">and </SPAN></P>
<PRE><SPAN class=grame></SPAN><SPAN class=grame><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">!</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(flags &amp; <SPAN class=spelle>format_no_copy</SPAN>)</SPAN> </PRE>
<P>then calls
</P>
<PRE><SPAN class=spelle><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">std::copy</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(first, last, out)</SPAN>. </PRE>
<P>Otherwise, for each match found,
<SPAN class="grame">if </SPAN></P>
<PRE><SPAN class=grame></SPAN><SPAN class=grame><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">!</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(flags &amp; <SPAN class=spelle>format_no_copy</SPAN>)</SPAN> </PRE>
<P>calls
</P>
<PRE><SPAN class=spelle><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">std::copy</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(<SPAN class=spelle>m.prefix</SPAN>().first, <SPAN class=spelle>m.prefix</SPAN>().last, out)</SPAN>, </PRE>
<P>and then calls
</P>
<PRE><SPAN class=spelle><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">m.format</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(out, <SPAN class=spelle>fmt</SPAN>, flags)</SPAN>. </PRE>
<P>Finally
<SPAN class="grame">if </SPAN></P>
<PRE><SPAN class=grame></SPAN><SPAN class=grame><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">!</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(flags &amp; <SPAN class=spelle>format_no_copy</SPAN>)</SPAN> </PRE>
<P>calls
</P>
<PRE><SPAN class=spelle><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">std::copy</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">(<SPAN class=spelle>last_m.suffix</SPAN>().first, <SPAN class=spelle>last_m,suffix</SPAN>().last, out) </SPAN></PRE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"></SPAN>where
<SPAN class="spelle">
<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">last_m</SPAN>
</SPAN>
is a copy of the last match found.
</P>
<P>If
<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">flags &amp;
<SPAN class="spelle">format_first_only</SPAN></SPAN>
is non-zero then only the first match found is replaced.</P>
<P><STRONG>Throws:</STRONG> <CODE>std::runtime_error</CODE> if the complexity of
matching the expression against an N character string begins to exceed O(N<SUP>2</SUP>),
or if the program runs out of stack space while matching the expression (if
Boost.regex is <A href="configuration.html">configured</A> in recursive mode),
or if the matcher exhausts it's permitted memory allocation (if Boost.regex is <A href="configuration.html">
configured</A> in non-recursive mode).</P>
<P><B> Returns:</B> <CODE>out</CODE>.
</P>
<PRE><A name=f2></A>template &lt;class traits, class Allocator, class charT&gt;
basic_string&lt;charT&gt; regex_replace(const basic_string&lt;charT&gt;&amp; s,
const <A href="basic_regex.html">basic_regex</A>&lt;charT, traits, Allocator&gt;&amp; e,
const basic_string&lt;charT&gt;&amp; fmt,
<A href="match_flag_type.html">match_flag_type flags = match_default</A>);</PRE>
<P><B> Effects:</B> Constructs an object <CODE>basic_string&lt;charT&gt; result</CODE>,
calls <CODE>regex_replace(back_inserter(result), s.begin(), s.end(), e, fmt,
flags)</CODE>, and then returns <CODE>result</CODE>.
<H3><A name="examples"></A>Examples</H3>
<P>The following <A href="../example/snippets/regex_replace_example.cpp">example</A>
takes C/C++ source code as input, and outputs syntax highlighted HTML code.</P>
<P></P>
<PRE><FONT color=#008080>#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;iterator&gt;
#include &lt;boost/regex.hpp&gt;
#include &lt;fstream&gt;
#include &lt;iostream&gt;
</FONT>
<FONT color=#000080><I>// purpose:
// takes the contents of a file and transform to
// syntax highlighted code in html format
</I></FONT>
boost::regex e1, e2;
<B>extern</B> <B>const</B> <B>char</B>* expression_text;
<B>extern</B> <B>const</B> <B>char</B>* format_string;
<B>extern</B> <B>const</B> <B>char</B>* pre_expression;
<B>extern</B> <B>const</B> <B>char</B>* pre_format;
<B>extern</B> <B>const</B> <B>char</B>* header_text;
<B>extern</B> <B>const</B> <B>char</B>* footer_text;
<B>void</B> load_file(std::string&amp; s, std::istream&amp; is)
{
s.erase();
s.reserve(is.rdbuf()-&gt;in_avail());
<B>char</B> c;
<B>while</B>(is.get(c))
{
<B>if</B>(s.capacity() == s.size())
s.reserve(s.capacity() * <FONT color=#000080>3</FONT>);
s.append(<FONT color=#000080>1</FONT>, c);
}
}
<B>int</B> main(<B>int</B> argc, <B>const</B> <B>char</B>** argv)
{
try{
e1.assign(expression_text);
e2.assign(pre_expression);
<B>for</B>(<B>int</B> i = <FONT color=#000080>1</FONT>; i &lt; argc; ++i)
{
std::cout &lt;&lt; <FONT color=#0000ff>"Processing file "</FONT> &lt;&lt; argv[i] &lt;&lt; std::endl;
std::ifstream fs(argv[i]);
std::string in;
load_file(in, fs);
std::string out_name(std::string(argv[i]) + std::string(<FONT color=#0000ff>".htm"</FONT>));
std::ofstream os(out_name.c_str());
os &lt;&lt; header_text;
<FONT color=#000080><I>// strip '&lt;' and '&gt;' first by outputting to a
</I></FONT> <FONT color=#000080><I>// temporary string stream
</I></FONT> std::ostringstream t(std::ios::out | std::ios::binary);
std::ostream_iterator&lt;<B>char</B>, <B>char</B>&gt; oi(t);
boost::regex_replace(oi, in.begin(), in.end(),
e2, pre_format, boost::match_default | boost::format_all);
<FONT color=#000080><I>// then output to final output stream
</I></FONT> <FONT color=#000080><I>// adding syntax highlighting:
</I></FONT> std::string s(t.str());
std::ostream_iterator&lt;<B>char</B>, <B>char</B>&gt; out(os);
boost::regex_replace(out, s.begin(), s.end(),
e1, format_string, boost::match_default | boost::format_all);
os &lt;&lt; footer_text;
}
}
<STRONG>catch</STRONG>(...)
{ <STRONG>return</STRONG> -1; }
<B>return</B> <FONT color=#000080>0</FONT>;
}
<B>extern</B> <B>const</B> <B>char</B>* pre_expression = <FONT color=#0000ff>"(&lt;)|(&gt;)|\\r"</FONT>;
<B>extern</B> <B>const</B> <B>char</B>* pre_format = <FONT color=#0000ff>"(?1&lt;)(?2&gt;)"</FONT>;
<B>const</B> <B>char</B>* expression_text = <FONT color=#000080><I>// preprocessor directives: index 1
</I></FONT> <FONT color=#0000ff>"(^[[:blank:]]*#(?:[^\\\\\\n]|\\\\[^\\n[:punct:][:word:]]*[\\n[:punct:][:word:]])*)|"
</FONT> <FONT color=#000080><I>// comment: index 2
</I></FONT> <FONT color=#0000ff>"(//[^\\n]*|/\\*.*?\\*/)|"
</FONT> <FONT color=#000080><I>// literals: index 3
</I></FONT> <FONT color=#0000ff>"\\&lt;([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\&gt;|"
</FONT> <FONT color=#000080><I>// string literals: index 4
</I></FONT> <FONT color=#0000ff>"('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
</FONT> <FONT color=#000080><I>// keywords: index 5
</I></FONT> <FONT color=#0000ff>"\\&lt;(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
</FONT> <FONT color=#0000ff>"|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
</FONT> <FONT color=#0000ff>"|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
</FONT> <FONT color=#0000ff>"|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
</FONT> <FONT color=#0000ff>"|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
</FONT> <FONT color=#0000ff>"|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
</FONT> <FONT color=#0000ff>"|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
</FONT> <FONT color=#0000ff>"|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
</FONT> <FONT color=#0000ff>"|using|virtual|void|volatile|wchar_t|while)\\&gt;"
</FONT> ;
<B>const</B> <B>char</B>* format_string = <FONT color=#0000ff>"(?1&lt;font color=\"#008040\"&gt;$&amp;&lt;/font&gt;)"
</FONT> <FONT color=#0000ff>"(?2&lt;I&gt;&lt;font color=\"#000080\"&gt;$&amp;&lt;/font&gt;&lt;/I&gt;)"
</FONT> <FONT color=#0000ff>"(?3&lt;font color=\"#0000A0\"&gt;$&amp;&lt;/font&gt;)"
</FONT> <FONT color=#0000ff>"(?4&lt;font color=\"#0000FF\"&gt;$&amp;&lt;/font&gt;)"
</FONT> <FONT color=#0000ff>"(?5&lt;B&gt;$&amp;&lt;/B&gt;)"</FONT>;
<B>const</B> <B>char</B>* header_text = <FONT color=#0000ff>"&lt;HTML&gt;\n&lt;HEAD&gt;\n"
</FONT> <FONT color=#0000ff>"&lt;TITLE&gt;Auto-generated html formated source&lt;/TITLE&gt;\n"
</FONT> <FONT color=#0000ff>"&lt;META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=windows-1252\"&gt;\n"
</FONT> <FONT color=#0000ff>"&lt;/HEAD&gt;\n"
</FONT> <FONT color=#0000ff>"&lt;BODY LINK=\"#0000ff\" VLINK=\"#800080\" BGCOLOR=\"#ffffff\"&gt;\n"
</FONT> <FONT color=#0000ff>"&lt;P&gt; &lt;/P&gt;\n&lt;PRE&gt;"</FONT>;
<B>const</B> <B>char</B>* footer_text = <FONT color=#0000ff>"&lt;/PRE&gt;\n&lt;/BODY&gt;\n\n"</FONT>;
</PRE>
<HR>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
17 May 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<P><I><EFBFBD> Copyright <a href="mailto:jm@regex.fsnet.co.uk">John Maddock</a>&nbsp;1998-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y" startspan --> 2003<!--webbot bot="Timestamp" endspan i-checksum="39359" --></I></P>
<P align="left"><I>Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting documentation.
Dr John Maddock makes no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.</I></P>
</body>
</html>