libkdepim

kregexp3.cpp

00001 /*  -*- c++ -*-
00002     kregexp3.cpp
00003 
00004     This file is part of libkdenetwork.
00005     Copyright (c) 2001 Marc Mutz <mutz@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU General Public License,
00009     version 2, as published by the Free Software Foundation.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this library; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020     In addition, as a special exception, the copyright holders give
00021     permission to link the code of this library with any edition of
00022     the Qt library by Trolltech AS, Norway (or with modified versions
00023     of Qt that use the same license as Qt), and distribute linked
00024     combinations including the two.  You must obey the GNU General
00025     Public License in all respects for all of the code used other than
00026     Qt.  If you modify this file, you may extend this exception to
00027     your version of the file, but you are not obligated to do so.  If
00028     you do not wish to do so, delete this exception statement from
00029     your version.
00030 */
00031 
00032 #include "kregexp3.h"
00033 
00034 // #define DEBUG_KREGEXP3
00035 
00036 #ifdef DEBUG_KREGEXP3
00037 #include <kdebug.h>
00038 #endif
00039 
00040 QString KRegExp3::replace( const QString & str,
00041                const QString & replacementStr,
00042                int start, bool global )
00043 {
00044   int oldpos, pos;
00045 
00046   //-------- parsing the replacementStr into
00047   //-------- literal parts and backreferences:
00048   QStringList     literalStrs;
00049   QValueList<int> backRefs;
00050 
00051   // Due to LTS: The regexp in unquoted form and with spaces:
00052   // \\ (\d) | \$ (\d) | \$ \{ (\d+) \}
00053   QRegExp rx( "\\\\(\\d)|\\$(\\d)|\\$\\{(\\d+)\\}" );
00054   QRegExp bbrx("\\\\");
00055   QRegExp brx("\\");
00056 
00057 #ifdef DEBUG_KREGEXP3
00058   kdDebug() << "Analyzing replacementStr: \"" + replacementStr + "\"" << endl;
00059 #endif
00060 
00061   oldpos = 0;
00062   pos = 0;
00063   while ( true ) {
00064     pos = rx.search( replacementStr, pos );
00065     
00066 #ifdef DEBUG_KREGEXP3
00067     kdDebug() << QString("  Found match at pos %1").arg(pos) << endl;
00068 #endif
00069 
00070     if ( pos < 0 ) {
00071       literalStrs << replacementStr.mid( oldpos )
00072     .replace( bbrx, "\\" )
00073     .replace( brx, "" );
00074 #ifdef DEBUG_KREGEXP3
00075       kdDebug() << "  No more matches. Last literal is \"" + literalStrs.last() + "\"" << endl;
00076 #endif
00077       break;
00078     } else {
00079       literalStrs << replacementStr.mid( oldpos, pos-oldpos )
00080     .replace( bbrx, "\\" )
00081     .replace( brx, "" );
00082 #ifdef DEBUG_KREGEXP3
00083       kdDebug() << QString("  Inserting \"") + literalStrs.last() + "\" as literal." << endl;
00084       kdDebug() << "    Searching for corresponding digit(s):" << endl;
00085 #endif
00086       for ( int i = 1 ; i < 4 ; i++ )
00087     if ( !rx.cap(i).isEmpty() ) {
00088       backRefs << rx.cap(i).toInt();
00089 #ifdef DEBUG_KREGEXP3
00090       kdDebug() << QString("      Found %1 at position %2 in the capturedTexts.")
00091             .arg(backRefs.last()).arg(i) << endl;
00092 #endif
00093       break;
00094     }
00095       pos += rx.matchedLength();
00096 #ifdef DEBUG_KREGEXP3
00097       kdDebug() << QString("  Setting new pos to %1.").arg(pos) << endl;
00098 #endif
00099       oldpos = pos;
00100     }
00101   }
00102 
00103 #ifdef DEBUG_KREGEXP3
00104   kdDebug() << "Finished the analysis of replacementStr!" << endl;
00105 #endif
00106   Q_ASSERT( literalStrs.count() == backRefs.count() + 1 );
00107 
00108   //-------- actual construction of the
00109   //-------- resulting QString
00110   QString result = "";
00111   oldpos = 0;
00112   pos = start;
00113 
00114   QStringList::Iterator sIt;
00115   QValueList<int>::Iterator iIt;
00116 
00117   if ( start < 0 )
00118     start += str.length();
00119 
00120 #ifdef DEBUG_KREGEXP3
00121   kdDebug() << "Constructing the resultant string starts now:" << endl;
00122 #endif
00123   
00124   while ( pos < (int)str.length() ) {
00125     pos = search( str, pos );
00126 
00127 #ifdef DEBUG_KREGEXP3
00128     kdDebug() << QString("  Found match at pos %1").arg(pos) << endl;
00129 #endif
00130 
00131     if ( pos < 0 ) {
00132       result += str.mid( oldpos );
00133 #ifdef DEBUG_KREGEXP3
00134       kdDebug() << "   No more matches. Adding trailing part from str:" << endl;
00135       kdDebug() << "    result == \"" + result + "\"" << endl;
00136 #endif
00137       break;
00138     } else {
00139       result += str.mid( oldpos, pos-oldpos );
00140 #ifdef DEBUG_KREGEXP3
00141       kdDebug() << "   Adding unchanged part from str:" << endl;
00142       kdDebug() << "    result == \"" + result + "\"" << endl;
00143 #endif
00144       for ( sIt = literalStrs.begin(), iIt = backRefs.begin() ;
00145             iIt != backRefs.end() ; ++sIt, ++iIt ) {
00146     result += (*sIt);
00147 #ifdef DEBUG_KREGEXP3
00148     kdDebug() << "   Adding literal replacement part:" << endl;
00149     kdDebug() << "    result == \"" + result + "\"" << endl;
00150 #endif
00151     result += cap( (*iIt) );
00152 #ifdef DEBUG_KREGEXP3
00153     kdDebug() << "   Adding captured string:" << endl;
00154     kdDebug() << "    result == \"" + result + "\"" << endl;
00155 #endif
00156       }
00157       result += (*sIt);
00158 #ifdef DEBUG_KREGEXP3
00159       kdDebug() << "   Adding literal replacement part:" << endl;
00160       kdDebug() << "    result == \"" + result + "\"" << endl;
00161 #endif
00162     }
00163     if (matchedLength() == 0 && pos == 0) {
00164       // if we matched the begin of the string, then better avoid endless
00165       // recursion
00166       result += str.mid( oldpos );
00167       break;
00168     }
00169     pos += matchedLength();
00170 #ifdef DEBUG_KREGEXP3
00171     kdDebug() << QString("  Setting new pos to %1.").arg(pos) << endl;
00172 #endif
00173     oldpos = pos;
00174 
00175     if ( !global ) {
00176       // only replace the first occurrence, so stop here:
00177       result += str.mid( oldpos );
00178       break;
00179     }
00180   }
00181 
00182   return result;
00183 }
KDE Home | KDE Accessibility Home | Description of Access Keys