Bug 211632 - Autoreplace doesn't handle multiple replacements in the same line properly
Summary: Autoreplace doesn't handle multiple replacements in the same line properly
Status: RESOLVED FIXED
Alias: None
Product: konversation
Classification: Applications
Component: general (show other bugs)
Version: 1.2
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Konversation Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-10-24 12:49 UTC by alab
Modified: 2009-12-15 08:47 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description alab 2009-10-24 12:49:48 UTC
+++ This bug was initially created as a clone of Bug #158910 +++

Following Autoreplacement

Use Regex: Yes
Replace in: Outgoing
Search: php/([^\s]+)
Replace: http://php.net/%1

One Line Input like:
Please read php/array_filter or php/filter

Expected Output:
Please read http://php.net/array_filter or http://php.net/filter

Actual Output:
Please read http://php.net/array_filter or http://php.net/array_filter
Comment 1 Travis McHenry 2009-12-15 08:47:50 UTC
commit a54b8543fa24de3bf6fe6993724b588a9e48a1b4
Author: Travis McHenry <wordsizzle@gmail.com>
Date:   Tue Dec 15 00:44:23 2009 -0700

    Fix an autoreplace bug and enable escaping
    
    Make it so we can do multiple replaces in a single line again by
    not replacing the content of the 'global' replace variable
    BUG:211632
    
    Make it so we can support %# in replacements  without it getting
    lost in regex land by allowing escaping (with %%#).If you're so
    inclined please review the big comment explaining why we can't
    just not remove the leftover %# to make sure I'm not shooting hot
    air.
    BUG:218332

diff --git a/src/application.cpp b/src/application.cpp
index cf61af5..79c7730 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -1007,18 +1007,27 @@ QString Application::doAutoreplace(const QString& text,bool output)
                     {
                         // remember captured patterns
                         QStringList captures = needleReg.capturedTexts();
+                        QString replaceWith = replacement;
 
-                        // replace %0 - %9 in regex groups
+                        replaceWith.replace("%%","%\x01"); // escape double %
+                        // replace %0-9 in regex groups
                         for (int capture=0;capture<captures.count();capture++)
                         {
-                            replacement.replace(QString("%%1").arg(capture),captures[capture]);
+                            QString search = QString("%%1").arg(capture);
+                            replaceWith.replace(search, captures[capture]);
                         }
-                        replacement.remove(QRegExp("%[0-9]"));
+                        //Explanation why this is important so we don't forget:
+                        //If somebody has a regex that say has a replacement of url.com/%1/%2 and the
+                        //regex can either match one or two patterns, if the 2nd pattern match is left,
+                        //the url is invalid (url.com/match/%2). This is expected regex behavior I'd assume.
+                        replaceWith.remove(QRegExp("%[0-9]"));
+
+                        replaceWith.replace("%\x01","%"); // return escaped % to normal
                         // allow for var expansion in autoreplace
-                        replacement = Konversation::doVarExpansion(replacement);
+                        replaceWith = Konversation::doVarExpansion(replaceWith);
                         // replace input with replacement
-                        line.replace(index, captures[0].length(), replacement);
-                        index += replacement.length();
+                        line.replace(index, captures[0].length(), replaceWith);
+                        index += replaceWith.length();
                     }
                 } while (index >= 0 && index < (int)line.length());
             }