Main Page   Namespace List   Compound List   File List   Compound Members   File Members  

replace.cc

Go to the documentation of this file.
00001 /*
00002  *
00003  *  This file  is part of the PCRE++ Class Library.
00004  *
00005  *  By  accessing  this software,  PCRE++, you  are  duly informed
00006  *  of and agree to be  bound  by the  conditions  described below
00007  *  in this notice:
00008  *
00009  *  This software product,  PCRE++,  is developed by Thomas Linden
00010  *  and copyrighted (C) 2002-2003 by Thomas Linden,with all rights 
00011  *  reserved.
00012  *
00013  *  There  is no charge for PCRE++ software.  You can redistribute
00014  *  it and/or modify it under the terms of the GNU  Lesser General
00015  *  Public License, which is incorporated by reference herein.
00016  *
00017  *  PCRE++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS,
00018  *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that
00019  *  the use of it will not infringe on any third party's intellec-
00020  *  tual property rights.
00021  *
00022  *  You should have received a copy of the GNU Lesser General Public
00023  *  License along with PCRE++.  Copies can also be obtained from:
00024  *
00025  *    http://www.gnu.org/licenses/lgpl.txt
00026  *
00027  *  or by writing to:
00028  *
00029  *  Free Software Foundation, Inc.
00030  *  59 Temple Place, Suite 330
00031  *  Boston, MA 02111-1307
00032  *  USA
00033  *
00034  *  Or contact:
00035  *
00036  *   "Thomas Linden" <tom@daemon.de>
00037  *
00038  *
00039  */
00040 
00041 
00042 #include "pcre++.h"
00043 
00044 using namespace std;
00045 using namespace pcrepp;
00046 
00047 /*
00048  * replace method
00049  */
00050 
00051 string Pcre::replace(const string& piece, const string& with) {
00052   /*
00053    * Pcre::replace version by "Marcus Kramer" <marcus.kramer@scherrer.de>
00054    */
00055   string Replaced(piece);
00056 
00057   bool bReplaced = false;
00058   int  iReplaced = -1;
00059 
00060   __pcredebug << "replace: " << piece << " with: " << with << endl;
00061 
00062   /*
00063    * certainly we need an anchor, we want to check if the whole arg is in brackets
00064    * //Pcre braces("^[^\\\\]\\(.*[^\\\\]\\)$"); // perlish: [^\\]\(.*[^\\]\)
00065    *
00066    * There's no reason, not to add brackets in general.
00067    * It's more comfortable, cause we wants to start with $1 at all, 
00068    * also if we set the whole arg in brackets!
00069    */
00070   
00071   /* recreate the p_pcre* objects to avoid memory leaks */
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   _expression = "(" + _expression + ")";
00082   Compile(_flags);
00083         
00084   if(search(piece)) {
00085     /* we found at least one match */
00086     
00087     // sure we must resolve $1 for ever piece we found especially for "g"
00088     // so let's just create that var, we resolve it when we needed!
00089     string use_with;
00090 
00091 
00092     if(!global_t) {
00093       // here we can resolve vars if option g is not set
00094       use_with = _replace_vars(with);
00095 
00096       if(matched() && matches() >= 1) {
00097         __pcredebug << "matches: " << matches() << endl;
00098         int len = get_match_end() - get_match_start() + 1;
00099         Replaced.replace(get_match_start(0), len, use_with);
00100         bReplaced  = true;
00101         iReplaced = 0;
00102       }
00103     }
00104     else {
00105       /* global replace */
00106 
00107       // in global replace we just need to remember our position
00108       // so let's initialize it first
00109       int match_pos = 0;
00110       while( search( Replaced, match_pos ) ) {
00111         int len = 0;
00112                                 
00113         // here we need to resolve the vars certainly for every hit.
00114         // could be different content sometimes!
00115         use_with = _replace_vars(with);
00116                                 
00117         len = get_match_end() - get_match_start() + 1;
00118         Replaced.replace(get_match_start(0), len, use_with);
00119                                 
00120         //# Next run should begin after the last char of the stuff we put in the text
00121         match_pos = ( use_with.length() - len ) + get_match_end() + 1;
00122 
00123         bReplaced  = true;
00124         ++iReplaced;
00125       }
00126     }
00127   }
00128   
00129   did_match   = bReplaced;
00130   num_matches = iReplaced;
00131 
00132   return Replaced;
00133 }
00134 
00135 
00136 
00137 
00138 
00139 string Pcre::_replace_vars(const string& piece) {
00140   /*
00141    * Pcre::_replace_vars version by "Marcus Kramer" <marcus.kramer@scherrer.de>
00142    */
00143   string with  = piece;
00144   Pcre dollar("\\$([0-9]+)");
00145 
00146   while ( dollar.search( with ) ) {
00147     // let's do some conversion first
00148     __pcredebug << "Pcre::dollar matched: " << piece << ". Match(0): " << dollar.get_match(0) << endl;
00149     int iBracketIndex = atoi( dollar.get_match(0).data() );
00150     string sBracketContent = get_match(iBracketIndex);
00151     
00152     // now we can splitt the stuff
00153     string sSubSplit = "\\$" + dollar.get_match(0);
00154     Pcre subsplit(sSubSplit);
00155                 
00156     // normally 2 (or more) parts, the one in front of and the other one after "$1"
00157     vector<string> splitted = subsplit.split(with); 
00158     string Replaced;
00159                 
00160     for(size_t pos=0; pos < splitted.size(); pos++) {
00161       if( pos == ( splitted.size() - 1 ) ) 
00162         Replaced += splitted[pos];
00163       else 
00164         Replaced += splitted[pos] + sBracketContent;
00165     }
00166     with = Replaced; // well, one part is done
00167   }
00168   return with;
00169 }

Generated on Tue Jul 1 00:57:23 2003 for PCRE++ by doxygen1.3-rc3