Confused by Replace versus Replace-All



  • A Q&A on StackOverflow wants to delete the second occurrence of “%20” in each line of text like that below. One of the answers offers the regular expression replacement of “(.*?\K%){2}\d+” with nothing (the empty string).

    When I use “Replace All” then the second occurrence is removed from all the lines, as wanted. When I try and replace them one-by-one using repeated clicks on the “Replace” button the expected text is highlighted but no changes are made. Repeated clicks on “Find next” also highlight the expected text.

    Something has gone wrong with my understanding of Notepad++.

    My name is %20John. my friend's name is %20john too.
    My name is %20paul. my friend's name is %20paul too.
    

    I am not interested in other ways of solving this simple task. My question is about what is happening. Why does Replace-All do what is wanted, but Replace does nothing?

    Debug info:
    Notepad++ v7.9.5 (32-bit)
    Build time : Mar 21 2021 - 02:09:07
    Path : C:\Program Files (x86)\Notepad++\notepad++.exe
    Admin mode : OFF
    Local Conf mode : OFF
    OS Name : Windows 10 Enterprise (64-bit)
    OS Version : 2009
    OS Build : 19042.985
    Current ANSI codepage : 1252
    Plugins : none



  • @AdrianTweeter said in Confused by Replace versus Replace-All:

    Why does Replace-All do what is wanted, but Replace does nothing?

    In short the use of the \K prevents the “Replace” function from correctly working. Notepad++ uses the Boost engine and Scintilla for all the heavy work (under the hood). It’s there that this failing is produced. I believe there may be some light in the tunnel as newer versions of the underlying processes rectifies this failing. We just need to wait on the Notepad++ developers to use the later version.

    There are numerous articles with solutions (especially ones from @guy038) where the \K is used and the mention of not using Replace, but Replace All.

    There are ways around it but that entails changing the regex and having to include a replacement whereas the \K allows for an empty replacement.

    Terry



  • @Terry-R said in Confused by Replace versus Replace-All:

    There are ways around it but that entails changing the regex

    A possible change could be
    (?-s)(.*?%\d+.+?)%\d+
    with the replacement field as being
    $1

    That would allow you to use the “single” Replace button.

    Terry



  • @Terry-R said in Confused by Replace versus Replace-All:

    Notepad++ uses the Boost engine … for all the heavy work (under the hood). It’s there that this failing is produced

    Actually, I think it is not involved with the regex engine at all. Meaning that it could be fixed at a Notepad++ level.

    What happens when Replace is pressed is that N++ looks at the active selection and does a “find”. If it finds the active selection, it knows it is able to do the replace (because the original selection was a match) and it does it. If it doesn’t find the active selection, it changes the selection to be the next “find” match (without replacing anything).

    The above may be a bit hard to grasp, but think of it this way: the Replace button has dual functionality. It can either do a Find Next (if the actively selected text DOESN’T match what you are trying to find) or a real replace (if it DOES).

    Well, when the \K syntax is involved, what is left selected after a Replace (of the Find Next variety) will NEVER match for the next press of Replace (which would be a true replace), so it never replaces. Okay, well, I think that sometimes it does, but it is rare.

    The reason it will never/rarely match has to do with the fact that the part before the \K is forgotten in the selection, but needs to be there (in the selection) for the Replace (true one) to do its job.

    I don’t know, this is really tough to explain, but I did look into it once. And the above is what I found. :-)



  • @Alan-Kilborn said in Confused by Replace versus Replace-All:

    Meaning that it could be fixed at a Notepad++ level.

    Very interesting. I thought some posts in this forum suggested it was with the Boost engine. I have been trying to find a specific post, maybe by @guy038 which I thought referred to a later version of Boost fixing this failing. But since I cannot find it (the search function on this forum isn’t helping) maybe I imagined it and your idea does have merit.

    Of course at the end of the day the \K fails with the single Replace button for whatever reason and is unlikely to be quickly remedied. It is easily circumvented. I actually prefer to not have to use it due to it’s shortcomings.

    Cheers
    Terry



  • @Terry-R said in Confused by Replace versus Replace-All:

    \K fails with the single Replace button for whatever reason

    This is true.

    It is easily circumvented.

    I would say this might not be true in all cases.
    Sometimes a true variable length lookbehind (which \K provides) is needed to solve a problem.

    I actually prefer to not have to use it due to it’s shortcomings.

    Are there other things wrong with it?
    Or just that it requires Replace All?



  • @Alan-Kilborn said in Confused by Replace versus Replace-All:

    Are there other things wrong with it?
    Or just that it requires Replace All?

    Well I think it is obvious that the Replace vs Replace All is the primary. Having to explain when providing a solution to users not to use single replace as it will very likely fail (I have had some instances where it has worked, as you stated earlier).

    I have used it in providing a solution but I do think that I could have provided a different solution without it, so I don’t (yet) believe it is absolutely needed, more convenient. I would be interested to see a problem where it was the only way to get a solution, no other way around it.

    Terry



  • Thank you Terry and Alan for the detailed answer to my question. I have seldom used the \K and so had not run into the problem before. Your explanations of why the behaviours are different are very interesting.


Log in to reply