1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>replace.cc Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3-rc3 -->
<center>
<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> </center>
<hr><h1>replace.cc</h1><a href="replace_8cc.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 <span class="comment">/*</span>
00002 <span class="comment"> *</span>
00003 <span class="comment"> * This file is part of the PCRE++ Class Library.</span>
00004 <span class="comment"> *</span>
00005 <span class="comment"> * By accessing this software, PCRE++, you are duly informed</span>
00006 <span class="comment"> * of and agree to be bound by the conditions described below</span>
00007 <span class="comment"> * in this notice:</span>
00008 <span class="comment"> *</span>
00009 <span class="comment"> * This software product, PCRE++, is developed by Thomas Linden</span>
00010 <span class="comment"> * and copyrighted (C) 2002-2003 by Thomas Linden,with all rights </span>
00011 <span class="comment"> * reserved.</span>
00012 <span class="comment"> *</span>
00013 <span class="comment"> * There is no charge for PCRE++ software. You can redistribute</span>
00014 <span class="comment"> * it and/or modify it under the terms of the GNU Lesser General</span>
00015 <span class="comment"> * Public License, which is incorporated by reference herein.</span>
00016 <span class="comment"> *</span>
00017 <span class="comment"> * PCRE++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS,</span>
00018 <span class="comment"> * OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that</span>
00019 <span class="comment"> * the use of it will not infringe on any third party's intellec-</span>
00020 <span class="comment"> * tual property rights.</span>
00021 <span class="comment"> *</span>
00022 <span class="comment"> * You should have received a copy of the GNU Lesser General Public</span>
00023 <span class="comment"> * License along with PCRE++. Copies can also be obtained from:</span>
00024 <span class="comment"> *</span>
00025 <span class="comment"> * http://www.gnu.org/licenses/lgpl.txt</span>
00026 <span class="comment"> *</span>
00027 <span class="comment"> * or by writing to:</span>
00028 <span class="comment"> *</span>
00029 <span class="comment"> * Free Software Foundation, Inc.</span>
00030 <span class="comment"> * 59 Temple Place, Suite 330</span>
00031 <span class="comment"> * Boston, MA 02111-1307</span>
00032 <span class="comment"> * USA</span>
00033 <span class="comment"> *</span>
00034 <span class="comment"> * Or contact:</span>
00035 <span class="comment"> *</span>
00036 <span class="comment"> * "Thomas Linden" <tom@daemon.de></span>
00037 <span class="comment"> *</span>
00038 <span class="comment"> *</span>
00039 <span class="comment"> */</span>
00040
00041
00042 <span class="preprocessor">#include "<a class="code" href="pcre++_8h.html">pcre++.h</a>"</span>
00043
00044 <span class="keyword">using</span> <span class="keyword">namespace </span>std;
00045 <span class="keyword">using</span> <span class="keyword">namespace </span>pcrepp;
00046
00047 <span class="comment">/*</span>
00048 <span class="comment"> * replace method</span>
00049 <span class="comment"> */</span>
00050
<a name="l00051"></a><a class="code" href="classpcrepp_1_1Pcre.html#a24">00051</a> string Pcre::replace(<span class="keyword">const</span> string& piece, <span class="keyword">const</span> string& with) {
00052 <span class="comment">/*</span>
00053 <span class="comment"> * Pcre::replace version by "Marcus Kramer" <marcus.kramer@scherrer.de></span>
00054 <span class="comment"> */</span>
00055 string Replaced(piece);
00056
00057 <span class="keywordtype">bool</span> bReplaced = <span class="keyword">false</span>;
00058 <span class="keywordtype">int</span> iReplaced = -1;
00059
00060 <a class="code" href="pcre++_8h.html#a0">__pcredebug</a> << <span class="stringliteral">"replace: "</span> << piece << <span class="stringliteral">" with: "</span> << with << endl;
00061
00062 <span class="comment">/*</span>
00063 <span class="comment"> * certainly we need an anchor, we want to check if the whole arg is in brackets</span>
00064 <span class="comment"> * //Pcre braces("^[^\\\\]\\(.*[^\\\\]\\)$"); // perlish: [^\\]\(.*[^\\]\)</span>
00065 <span class="comment"> *</span>
00066 <span class="comment"> * There's no reason, not to add brackets in general.</span>
00067 <span class="comment"> * It's more comfortable, cause we wants to start with $1 at all, </span>
00068 <span class="comment"> * also if we set the whole arg in brackets!</span>
00069 <span class="comment"> */</span>
00070
00071 <span class="comment">/* recreate the p_pcre* objects to avoid memory leaks */</span>
00072 pcre_free(p_pcre);
00073 pcre_free(p_pcre_extra);
00074
00075 pcre *_p = NULL;
00076 pcre_extra *_e = NULL;;
00077
00078 p_pcre = _p;
00079 p_pcre_extra = _e;
00080
00081 <span class="keywordflow">if</span> (! _have_paren ) {
00082 string::size_type p_open, p_close;
00083 p_open = _expression.find_first_of(<span class="stringliteral">"("</span>);
00084 p_close = _expression.find_first_of(<span class="stringliteral">")"</span>);
00085 <span class="keywordflow">if</span> ( p_open == string::npos && p_close == string::npos ) {
00086 <span class="comment">/*</span>
00087 <span class="comment"> * Well, _expression completely lacks of parens, which are</span>
00088 <span class="comment"> * required for search/replace operation. So add parens automatically.</span>
00089 <span class="comment"> * Note, that we add 2 pairs of parens so that we finally have $0 matchin</span>
00090 <span class="comment"> * the whole expression and $1 matching the inner side (which is in this</span>
00091 <span class="comment"> * case the very same string.</span>
00092 <span class="comment"> * We do this for perl compatibility. If the expression already contains</span>
00093 <span class="comment"> * parens, the whole match will produce $0 for us, so in this case we</span>
00094 <span class="comment"> * have no problem</span>
00095 <span class="comment"> */</span>
00096 _expression = <span class="stringliteral">"(("</span> + _expression + <span class="stringliteral">"))"</span>;
00097 }
00098 <span class="keywordflow">else</span> {
00099 <span class="comment">/*</span>
00100 <span class="comment"> * Add parens to the very beginning and end of the expression</span>
00101 <span class="comment"> * so that we have $0. I don't care if the user already supplied</span>
00102 <span class="comment"> * double-parentesed experssion (e.g. "((1))"), because PCRE seems</span>
00103 <span class="comment"> * to eat redundant parenteses, e.g. "((((1))))" returns the same</span>
00104 <span class="comment"> * result as "((1))".</span>
00105 <span class="comment"> */</span>
00106 _expression = <span class="stringliteral">"("</span> + _expression;
00107 _expression=_expression + <span class="stringliteral">")"</span>;
00108 }
00109
00110 _have_paren = <span class="keyword">true</span>;
00111 }
00112
00113 <a class="code" href="pcre++_8h.html#a0">__pcredebug</a> << <span class="stringliteral">"_expression: "</span> << _expression << endl;
00114
00115 Compile(_flags);
00116
00117 <span class="keywordflow">if</span>(<a class="code" href="classpcrepp_1_1Pcre.html#a8">search</a>(piece)) {
00118 <span class="comment">/* we found at least one match */</span>
00119
00120 <span class="comment">// sure we must resolve $1 for ever piece we found especially for "g"</span>
00121 <span class="comment">// so let's just create that var, we resolve it when we needed!</span>
00122 string use_with;
00123
00124
00125 <span class="keywordflow">if</span>(!global_t) {
00126 <span class="comment">// here we can resolve vars if option g is not set</span>
00127 use_with = _replace_vars(with);
00128
00129 <span class="keywordflow">if</span>(<a class="code" href="classpcrepp_1_1Pcre.html#a17">matched</a>() && <a class="code" href="classpcrepp_1_1Pcre.html#a18">matches</a>() >= 1) {
00130 <a class="code" href="pcre++_8h.html#a0">__pcredebug</a> << <span class="stringliteral">"matches: "</span> << <a class="code" href="classpcrepp_1_1Pcre.html#a18">matches</a>() << endl;
00131 <span class="keywordtype">int</span> len = <a class="code" href="classpcrepp_1_1Pcre.html#a15">get_match_end</a>() - <a class="code" href="classpcrepp_1_1Pcre.html#a14">get_match_start</a>() + 1;
00132 Replaced.replace(<a class="code" href="classpcrepp_1_1Pcre.html#a14">get_match_start</a>(0), len, use_with);
00133 bReplaced = <span class="keyword">true</span>;
00134 iReplaced = 0;
00135 }
00136 }
00137 <span class="keywordflow">else</span> {
00138 <span class="comment">/* global replace */</span>
00139
00140 <span class="comment">// in global replace we just need to remember our position</span>
00141 <span class="comment">// so let's initialize it first</span>
00142 <span class="keywordtype">int</span> match_pos = 0;
00143 <span class="keywordflow">while</span>( <a class="code" href="classpcrepp_1_1Pcre.html#a8">search</a>( Replaced, match_pos ) ) {
00144 <span class="keywordtype">int</span> len = 0;
00145
00146 <span class="comment">// here we need to resolve the vars certainly for every hit.</span>
00147 <span class="comment">// could be different content sometimes!</span>
00148 use_with = _replace_vars(with);
00149
00150 len = <a class="code" href="classpcrepp_1_1Pcre.html#a15">get_match_end</a>() - <a class="code" href="classpcrepp_1_1Pcre.html#a14">get_match_start</a>() + 1;
00151 Replaced.replace(<a class="code" href="classpcrepp_1_1Pcre.html#a14">get_match_start</a>(0), len, use_with);
00152
00153 <span class="comment">//# Next run should begin after the last char of the stuff we put in the text</span>
00154 match_pos = ( use_with.length() - len ) + <a class="code" href="classpcrepp_1_1Pcre.html#a15">get_match_end</a>() + 1;
00155
00156 bReplaced = <span class="keyword">true</span>;
00157 ++iReplaced;
00158 }
00159 }
00160 }
00161
00162 did_match = bReplaced;
00163 num_matches = iReplaced;
00164
00165 <span class="keywordflow">return</span> Replaced;
00166 }
00167
00168
00169
00170
00171
00172 string Pcre::_replace_vars(<span class="keyword">const</span> string& piece) {
00173 <span class="comment">/*</span>
00174 <span class="comment"> * Pcre::_replace_vars version by "Marcus Kramer" <marcus.kramer@scherrer.de></span>
00175 <span class="comment"> */</span>
00176 string with = piece;
00177 <a class="code" href="classpcrepp_1_1Pcre.html#a0">Pcre</a> dollar(<span class="stringliteral">"\\$([0-9]+)"</span>);
00178
00179 <span class="keywordflow">while</span> ( dollar.search( with ) ) {
00180 <span class="comment">// let's do some conversion first</span>
00181 <a class="code" href="pcre++_8h.html#a0">__pcredebug</a> << <span class="stringliteral">"Pcre::dollar matched: "</span> << piece << <span class="stringliteral">". Match(0): "</span> << dollar.get_match(0) << endl;
00182 <span class="keywordtype">int</span> iBracketIndex = atoi( dollar.get_match(0).data() );
00183 string sBracketContent = <a class="code" href="classpcrepp_1_1Pcre.html#a11">get_match</a>(iBracketIndex);
00184
00185 <span class="comment">// now we can splitt the stuff</span>
00186 string sSubSplit = <span class="stringliteral">"\\$"</span> + dollar.get_match(0);
00187 <a class="code" href="classpcrepp_1_1Pcre.html#a0">Pcre</a> subsplit(sSubSplit);
00188
00189 <span class="comment">// normally 2 (or more) parts, the one in front of and the other one after "$1"</span>
00190 vector<string> splitted = subsplit.split(with);
00191 string Replaced;
00192
00193 <span class="keywordflow">for</span>(size_t pos=0; pos < splitted.size(); pos++) {
00194 <span class="keywordflow">if</span>( pos == ( splitted.size() - 1 ) )
00195 Replaced += splitted[pos];
00196 <span class="keywordflow">else</span>
00197 Replaced += splitted[pos] + sBracketContent;
00198 }
00199 with = Replaced; <span class="comment">// well, one part is done</span>
00200 }
00201 <span class="keywordflow">return</span> with;
00202 }
</pre></div><hr><address style="align: right;"><small>Generated on Wed Aug 25 01:38:04 2004 for PCRE++ by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0
width=110 height=53></a>1.3-rc3 </small></address>
</body>
</html>
|