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   if ( _expression[0] != '(' )
00082     _expression = "(" + _expression;
00083 
00084   if ( _expression[_expression.size()-1] != ')' )
00085     _expression=_expression + ")"; 
00086 
00087   Compile(_flags);
00088         
00089   if(search(piece)) {
00090     /* we found at least one match */
00091     
00092     // sure we must resolve $1 for ever piece we found especially for "g"
00093     // so let's just create that var, we resolve it when we needed!
00094     string use_with;
00095 
00096 
00097     if(!global_t) {
00098       // here we can resolve vars if option g is not set
00099       use_with = _replace_vars(with);
00100 
00101       if(matched() && matches() >= 1) {
00102         __pcredebug << "matches: " << matches() << endl;
00103         int len = get_match_end() - get_match_start() + 1;
00104         Replaced.replace(get_match_start(0), len, use_with);
00105         bReplaced  = true;
00106         iReplaced = 0;
00107       }
00108     }
00109     else {
00110       /* global replace */
00111 
00112       // in global replace we just need to remember our position
00113       // so let's initialize it first
00114       int match_pos = 0;
00115       while( search( Replaced, match_pos ) ) {
00116         int len = 0;
00117                                 
00118         // here we need to resolve the vars certainly for every hit.
00119         // could be different content sometimes!
00120         use_with = _replace_vars(with);
00121                                 
00122         len = get_match_end() - get_match_start() + 1;
00123         Replaced.replace(get_match_start(0), len, use_with);
00124                                 
00125         //# Next run should begin after the last char of the stuff we put in the text
00126         match_pos = ( use_with.length() - len ) + get_match_end() + 1;
00127 
00128         bReplaced  = true;
00129         ++iReplaced;
00130       }
00131     }
00132   }
00133   
00134   did_match   = bReplaced;
00135   num_matches = iReplaced;
00136 
00137   return Replaced;
00138 }
00139 
00140 
00141 
00142 
00143 
00144 string Pcre::_replace_vars(const string& piece) {
00145   /*
00146    * Pcre::_replace_vars version by "Marcus Kramer" <marcus.kramer@scherrer.de>
00147    */
00148   string with  = piece;
00149   Pcre dollar("\\$([0-9]+)");
00150 
00151   while ( dollar.search( with ) ) {
00152     // let's do some conversion first
00153     __pcredebug << "Pcre::dollar matched: " << piece << ". Match(0): " << dollar.get_match(0) << endl;
00154     int iBracketIndex = atoi( dollar.get_match(0).data() );
00155     string sBracketContent = get_match(iBracketIndex);
00156     
00157     // now we can splitt the stuff
00158     string sSubSplit = "\\$" + dollar.get_match(0);
00159     Pcre subsplit(sSubSplit);
00160                 
00161     // normally 2 (or more) parts, the one in front of and the other one after "$1"
00162     vector<string> splitted = subsplit.split(with); 
00163     string Replaced;
00164                 
00165     for(size_t pos=0; pos < splitted.size(); pos++) {
00166       if( pos == ( splitted.size() - 1 ) ) 
00167         Replaced += splitted[pos];
00168       else 
00169         Replaced += splitted[pos] + sBracketContent;
00170     }
00171     with = Replaced; // well, one part is done
00172   }
00173   return with;
00174 }

Generated on Wed Jun 16 00:22:32 2004 for PCRE++ by doxygen1.3-rc3