File: replace_8cc-source.html

package info (click to toggle)
libpcre%2B%2B 0.9.5-5.1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 2,608 kB
  • sloc: sh: 9,165; cpp: 835; makefile: 78
file content (216 lines) | stat: -rw-r--r-- 13,739 bytes parent folder | download | duplicates (5)
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> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; </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" &lt;tom@daemon.de&gt;</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&amp; piece, <span class="keyword">const</span> string&amp; with) {
00052   <span class="comment">/*</span>
00053 <span class="comment">   * Pcre::replace version by "Marcus Kramer" &lt;marcus.kramer@scherrer.de&gt;</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> &lt;&lt; <span class="stringliteral">"replace: "</span> &lt;&lt; piece &lt;&lt; <span class="stringliteral">" with: "</span> &lt;&lt; with &lt;&lt; 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 &amp;&amp; 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> &lt;&lt; <span class="stringliteral">"_expression: "</span> &lt;&lt; _expression &lt;&lt; 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>() &amp;&amp; <a class="code" href="classpcrepp_1_1Pcre.html#a18">matches</a>() &gt;= 1) {
00130         <a class="code" href="pcre++_8h.html#a0">__pcredebug</a> &lt;&lt; <span class="stringliteral">"matches: "</span> &lt;&lt; <a class="code" href="classpcrepp_1_1Pcre.html#a18">matches</a>() &lt;&lt; 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&amp; piece) {
00173   <span class="comment">/*</span>
00174 <span class="comment">   * Pcre::_replace_vars version by "Marcus Kramer" &lt;marcus.kramer@scherrer.de&gt;</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> &lt;&lt; <span class="stringliteral">"Pcre::dollar matched: "</span> &lt;&lt; piece &lt;&lt; <span class="stringliteral">". Match(0): "</span> &lt;&lt; dollar.get_match(0) &lt;&lt; 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&lt;string&gt; splitted = subsplit.split(with); 
00191     string Replaced;
00192                 
00193     <span class="keywordflow">for</span>(size_t pos=0; pos &lt; 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>