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 
00046 /*
00047  * replace method
00048  */
00049 
00050 string Pcre::replace(const string& piece, const string& with) {
00051   /*
00052    * Pcre::replace version by "Marcus Kramer" <marcus.kramer@scherrer.de>
00053    */
00054   string Replaced(piece);
00055 
00056   bool bReplaced = false;
00057   int  iReplaced = -1;
00058 
00059   __pcredebug << "replace: " << piece << " with: " << with << endl;
00060 
00061   /*
00062    * certainly we need an anchor, we want to check if the whole arg is in brackets
00063    * //Pcre braces("^[^\\\\]\\(.*[^\\\\]\\)$"); // perlish: [^\\]\(.*[^\\]\)
00064    *
00065    * There's no reason, not to add brackets in general.
00066    * It's more comfortable, cause we wants to start with $1 at all, 
00067    * also if we set the whole arg in brackets!
00068    */
00069   
00070   /* recreate the p_pcre* objects to avoid memory leaks */
00071   pcre_free(p_pcre);
00072   pcre_free(p_pcre_extra);
00073   
00074   pcre       *_p = NULL;
00075   pcre_extra *_e = NULL;;
00076         
00077   p_pcre = _p;
00078   p_pcre_extra = _e;
00079         
00080   _expression = "(" + _expression + ")";
00081   Compile(_flags);
00082         
00083   if(search(piece)) {
00084     /* we found at least one match */
00085     
00086     // sure we must resolve $1 for ever piece we found especially for "g"
00087     // so let's just create that var, we resolve it when we needed!
00088     string use_with;
00089 
00090 
00091     if(!global_t) {
00092       // here we can resolve vars if option g is not set
00093       use_with = _replace_vars(with);
00094 
00095       if(matched() && matches() >= 1) {
00096         __pcredebug << "matches: " << matches() << endl;
00097         int len = get_match_end() - get_match_start() + 1;
00098         Replaced.replace(get_match_start(0), len, use_with);
00099         bReplaced  = true;
00100         iReplaced = 0;
00101       }
00102     }
00103     else {
00104       /* global replace */
00105 
00106       // in global replace we just need to remember our position
00107       // so let's initialize it first
00108       int match_pos = 0;
00109       while( search( Replaced, match_pos ) ) {
00110         int len = 0;
00111                                 
00112         // here we need to resolve the vars certainly for every hit.
00113         // could be different content sometimes!
00114         use_with = _replace_vars(with);
00115                                 
00116         len = get_match_end() - get_match_start() + 1;
00117         Replaced.replace(get_match_start(0), len, use_with);
00118                                 
00119         //# Next run should begin after the last char of the stuff we put in the text
00120         match_pos = ( use_with.length() - len ) + get_match_end() + 1;
00121 
00122         bReplaced  = true;
00123         ++iReplaced;
00124       }
00125     }
00126   }
00127   
00128   did_match   = bReplaced;
00129   num_matches = iReplaced;
00130 
00131   return Replaced;
00132 }
00133 
00134 
00135 
00136 
00137 
00138 string Pcre::_replace_vars(const string& piece) {
00139   /*
00140    * Pcre::_replace_vars version by "Marcus Kramer" <marcus.kramer@scherrer.de>
00141    */
00142   string with  = piece;
00143   Pcre dollar("\\$([0-9]+)");
00144 
00145   while ( dollar.search( with ) ) {
00146     // let's do some conversion first
00147     __pcredebug << "Pcre::dollar matched: " << piece << ". Match(0): " << dollar.get_match(0) << endl;
00148     int iBracketIndex = atoi( dollar.get_match(0).data() );
00149     string sBracketContent = get_match(iBracketIndex);
00150     
00151     // now we can splitt the stuff
00152     string sSubSplit = "\\$" + dollar.get_match(0);
00153     Pcre subsplit(sSubSplit);
00154                 
00155     // normally 2 (or more) parts, the one in front of and the other one after "$1"
00156     Array splitted = subsplit.split(with); 
00157     string Replaced;
00158                 
00159     for(size_t pos=0; pos < splitted.size(); pos++) {
00160       if( pos == ( splitted.size() - 1 ) ) 
00161         Replaced += splitted[pos];
00162       else 
00163         Replaced += splitted[pos] + sBracketContent;
00164     }
00165     with = Replaced; // well, one part is done
00166   }
00167   return with;
00168 }

Generated on Wed Jun 25 00:39:01 2003 for PCRE++ by doxygen1.3-rc3