Community
    • Login

    Search++ (\W)'(\w) regex replace failure

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    41 Posts 5 Posters 1.4k Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M Andre Z EckenrodeM Online
      M Andre Z Eckenrode @Coises
      last edited by

      @Coises said:

      Is he also using 32-bit Notepad++?

      His routinely-used copy is v8.9.3 x64 portable.

      1 Reply Last reply Reply Quote 1
      • CoisesC Online
        Coises @M Andre Z Eckenrode
        last edited by

        @M-Andre-Z-Eckenrode said:

        About my brother’s initial failures to get Search++ to load in his portable copy: His first four or so tries were attempted in different virtual machines on his computer, including the very first one being Windows 11’s built-in “Sandbox”. All of them failed with messages such as “The specified module could not be found” and “Search++.dll is not compatible with the current version of Notepad++”. But when he tried the same set of files on his real machine, it worked.

        At least I was able to figure out the cause of this problem. The ICU (International Components for Unicode) libraries that I use require a specific Microsoft redistributable library. I never noticed, and most people probably have it installed already as part of installing something else, just as I do. It doesn’t automatically carry over to virtual machines or sandboxes, though.

        There are a couple potential solutions (and if nothing else works out, I can at least explain in the readme how to install the redistributable). Thank you for reporting this.

        M Andre Z EckenrodeM 1 Reply Last reply Reply Quote 0
        • M Andre Z EckenrodeM Online
          M Andre Z Eckenrode @Coises
          last edited by

          @Coises said:

          At least I was able to figure out the cause of this problem.

          Glad to hear that worked out.

          @Coises said:

          Have you ever noticed arbitrary junk character replacements with any other regular expression / replacement pairs, or only with this particular one?

          I just tried a somewhat different regex experiment. I copied a list of words beginning with the letter a from a web page and pasted them into N++, then utilized Find (\W)a(\w) and Replace \1z\2 and stepped through. Out of 221 words, 21 replacements resulted in letters other than z being substituted for a. In a few cases, there was a letter other than z, followed by z itself, and followed again by another non-z letter. In a few other cases, extra line breaks were inserted mid-word. Note that in this experiment, no dashes (-) were inserted, as they often were in my previous experiments involving ' and ’. Presumably, that’s some sort of clue.

          M Andre Z EckenrodeM 1 Reply Last reply Reply Quote 0
          • M Andre Z EckenrodeM Online
            M Andre Z Eckenrode @M Andre Z Eckenrode
            last edited by

            @Coises

            And just now tried Find (\w)a(\w) and Replace \1z\2 with the same list of words, which definitely resulted in at least one anomalous replacement (average became avevzie), possibly more, but the mistakes are more difficult to spot at a glance in this case.

            CoisesC 1 Reply Last reply Reply Quote 1
            • CoisesC Online
              Coises @M Andre Z Eckenrode
              last edited by

              @M-Andre-Z-Eckenrode said:

              @Coises

              And just now tried Find (\w)a(\w) and Replace \1z\2 with the same list of words, which definitely resulted in at least one anomalous replacement (average became avevzie), possibly more, but the mistakes are more difficult to spot at a glance in this case.

              I hate continuing to bother you about this with different questions, but I am so stumped. Have you noticed:

              1. Do bad substitutions happen if the document is set as UTF-8, or is it specific to ANSI? (For a test, just use Encoding | Convert to UTF-8 on a document containing your test text before trying to Replace.)

              2. Have you ever seen a bad replacement where the replacement string did not use a capturing group reference (like \1 or \2 or $1 or $2)?

              M Andre Z EckenrodeM 1 Reply Last reply Reply Quote 0
              • M Andre Z EckenrodeM Online
                M Andre Z Eckenrode @Coises
                last edited by

                @Coises said:

                Do bad substitutions happen if the document is set as UTF-8, or is it specific to ANSI?

                I’ve experienced it with both at this point.

                Have you ever seen a bad replacement where the replacement string did not use a capturing group reference

                Not that I’ve noticed so far.

                New test:

                I used the same list of words, but inserted the number 2 between the second and third letters of all words that consisted of at least three letters, then stepped through using Find ([a-z])\d([a-z]) and Replace \1\2. There are anomalies. Examples include:

                ac2ademic became adjdemic

                ad2ministration became a
                ginistration

                CoisesC 1 Reply Last reply Reply Quote 1
                • CoisesC Online
                  Coises @M Andre Z Eckenrode
                  last edited by

                  @M-Andre-Z-Eckenrode

                  I think I may have found the cause.

                  Would you try installing this version:

                  https://github.com/Coises/SearchPlusPlus/releases/tag/v0.6.3.2

                  and see if the problem goes away?

                  If the problem is what I think it is, this will make it go away. It isn’t a good solution (it will cause serious inefficiency for large files), but if you no longer see the problem with this version, I’ll know I’ve almost certainly identified the cause, and I can work on a proper resolution.

                  Thank you so much for all your effort.

                  M Andre Z EckenrodeM 1 Reply Last reply Reply Quote 0
                  • M Andre Z EckenrodeM Online
                    M Andre Z Eckenrode @Coises
                    last edited by

                    @Coises said:

                    Would you try installing this version

                    With v0.6.3.2 in place, I re-ran several of the tests I’ve been doing, and found no anomalies this time, so that seems to have taken care of it. Thank YOU! Out of curiosity, is there any kind of basic explanation you can relay in layman’s terms for why it was doing what it was doing?

                    CoisesC 1 Reply Last reply Reply Quote 2
                    • CoisesC Online
                      Coises @M Andre Z Eckenrode
                      last edited by

                      @M-Andre-Z-Eckenrode said:
                      With v0.6.3.2 in place, I re-ran several of the tests I’ve been doing, and found no anomalies this time, so that seems to have taken care of it. Thank YOU!

                      Thank you. This error has been there since I first designed this regular expression search technique, in Columns++. It just apparently only shows up in rare circumstances. I’ve still never seen it.

                      Out of curiosity, is there any kind of basic explanation you can relay in layman’s terms for why it was doing what it was doing?

                      Notepad++ uses an open source component called Scintilla to display editable text. Scintilla maintains the text in an internal “split buffer,” meaning that there can be a gap at an arbitrary position within the text. It uses that gap to be able to make changes that add or remove characters in the middle of the text without having to copy all the following text to a new location every time there’s one small change.

                      For a few reasons, when I implemented search, I wanted to use the same regular expression engine that Notepad++ uses, Boost.regex, but I wanted to include my own copy in the plugin and manage it directly, rather than going through the hybrid Scintilla/Boost interface that Notepad++ exposes, and I wanted to access the Scintilla split buffer directly. To do that, I had to create something called iterators.

                      In C++, an iterator is essentially an indirect way of referencing data that has simple operations like “move to the next character” and “tell me what character you’re pointed at.” I designed iterators for UTF-8, for single-byte character set ANSI and for double-byte character set ANSI that could traverse the Scintilla buffer, mind the gap, and return the results to the Boost.regex engine as if it were seeing a contiguous string of UTF-32 Unicode characters, regardless of the actual encoding.

                      Now, there’s a caveat when you ask Scintilla for the location of its internal buffer positions. You get two segments (because of the gap). But Scintilla warns that you can’t trust those positions once you do anything else in Scintilla, or once any user interaction is possible (even if the user doesn’t change the text). So I made sure to “invalidate” my internal pointers whenever control left my plugin: such as between finding text and changing it.

                      In order to ask Boost.regex for the replacement string when doing a change, I have to keep a particular Boost.regex structure that references the original match, so it knows how to interpret capture group substitutions. I was careful to invalidate the buffer pointers before I called Boost.regex.format. Except…

                      The match structure in Boost.regex doesn’t store the Scintilla character positions of the match. It stores iterators. And the iterators I designed, to be as efficient as possible, hold copies of the pointers into the Scintilla split buffer. So invalidating the pointers I use to generate iterators for Boost.regex does nothing to the iterators Boost.regex already stored in the match structure.

                      For reasons I can’t guess, both you and your brother seem to have something about your systems that causes Scintilla to reposition the gap in its internal buffer between find and replace. It never seems to happen here, but I finally realized that my attempt to protect against that happening is ineffective.

                      What I did to test was add a Scintilla call each time I invalidate the buffer pointers that causes Scintilla to move everything to the beginning and put the gap at the end. That means all the iterators will have the same pointers. It’s not a good long-term solution, though, because in a large file moving the gap to the end every single time anything changes could make response sluggish.

                      So it might take me a little while to decide on the best solution. I’m glad you documented the error so well. Now I know what to fix, I just have to work out the best way to do it.

                      M Andre Z EckenrodeM 1 Reply Last reply Reply Quote 5
                      • M Andre Z EckenrodeM Online
                        M Andre Z Eckenrode @Coises
                        last edited by

                        Thank you, @Coises, and best wishes for a long-term solution.

                        1 Reply Last reply Reply Quote 1

                        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                        With your input, this post could be even better 💗

                        Register Login
                        • First post
                          Last post
                        The Community of users of the Notepad++ text editor.
                        Powered by NodeBB | Contributors