Community
    • Login

    Negative lookbehind regular expression not working on Notepad++

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    43 Posts 6 Posters 1.2k Views
    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.
    • guy038G
      guy038
      last edited by

      Hello, @peterjones and All,

      Peter, Done ! Refer to :

      https://community.notepad-plus-plus.org/topic/26812/generic-regex-how-to-use-the-couple-of-backtracking-control-verbs-skip-fail-or-skip-f-in-regexes

      I also added a link to this post in your FAQ: Generic Regular Expression (regex) Formulas post.

      Best Regards,

      guy038

      dr ramaanandD 1 Reply Last reply Reply Quote 3
      • dr ramaanandD
        dr ramaanand @guy038
        last edited by dr ramaanand

        @guy038 So, if you have an alternative method to the (*SKIP)(*FAIL) method for the block posted right at the top of this thread for testing to match the same string you posted in post#16 above, please post it here

        dr ramaanandD 1 Reply Last reply Reply Quote 0
        • dr ramaanandD
          dr ramaanand @dr ramaanand
          last edited by dr ramaanand

          @guy038 you can use the idea mentioned at www.drregex.com/2019/02/variable-length-lookbehinds-actually.html?m=1 if you please, for the above RegEx. @PeterJones can include that formula in the Notepad++ manual also, if he pleases.

          Alan KilbornA 1 Reply Last reply Reply Quote 0
          • Alan KilbornA
            Alan Kilborn @dr ramaanand
            last edited by Alan Kilborn

            @dr-ramaanand said:

            www.drregex.com/2019/02/variable-length-lookbehinds-actually.html?m=1

            Doesn’t appear to be a valid link, in fact, it seems to point back to the N++ Community site??

            THIS is probably the correct link.

            dr ramaanandD 1 Reply Last reply Reply Quote 1
            • dr ramaanandD
              dr ramaanand @Alan Kilborn
              last edited by dr ramaanand

              @guy038 The answer by User Doqnach mentioned at https://stackoverflow.com/questions/25563891/variable-length-look-behind can be used as an example.

              Alan KilbornA 1 Reply Last reply Reply Quote 0
              • Alan KilbornA
                Alan Kilborn @dr ramaanand
                last edited by

                @dr-ramaanand said:

                The answer by User Doqnach mentioned at … can be used as an example.

                Well, trying that (/(?=(?=(?'a'[\s\S]*))(?'b'eat_(?:apple|pear|orange)_(?=\k'a'\z)|(?<=(?=x^|(?&b))[\s\S])))today|yesterday) in Notepad++ yields:

                bf2380ce-2d50-4d34-8670-d833b3f43479-image.png

                This is an error message I don’t think I’ve seen before.

                Note that I tried it on a smallish file where nothing would have matched.

                dr ramaanandD 1 Reply Last reply Reply Quote 0
                • dr ramaanandD
                  dr ramaanand @Alan Kilborn
                  last edited by dr ramaanand

                  @Alan-Kilborn That RegEx should be (?=(?=(?'a'[\s\S]*))(?'b'eat_(?:apple|pear|orange)_(?=\k'a'\z)|(?<=(?=x^|(?&b))[\s\S])))today|yesterday - I corrected it on stackoverflow but my edit is awaiting moderation (others can see it with my corrections only after my edit gets approved). For your information, those are positive look behinds with a capture group named ‘a’ and a capture group named ‘b’ and need to be changed to negative look behinds. I am unable to skip anything with this or this. I want the result to be like in post#16

                  dr ramaanandD 1 Reply Last reply Reply Quote 0
                  • dr ramaanandD
                    dr ramaanand @dr ramaanand
                    last edited by dr ramaanand

                    This post is deleted!
                    1 Reply Last reply Reply Quote 0
                    • guy038G
                      guy038
                      last edited by guy038

                      Hello, @dr-ramaanand and All,

                      Ah, I just having some spare time to answer your specific problem !

                      As I said in a previous post, you cannot use look-behinds as they do NOT support variable quantifiers ! That’s why I proposed a method with the ((SKIP)(*F) feature, which works properly.


                      In order to found out other methods, let’s begin with a simplified problem :

                      Starting with this INPUT text :

                      DEF  ABCDEF   ABC     DEF  ABCDEF   XYZDEF   ABCDEF
                      

                      The following regex S/R :

                      FIND (?-is)ABCDEF(*SKIP)(*F)|DEF

                      REPLACE 12345

                      Matches only the DEF string when NOT preceded with the ABC string

                      After the replacement, we get this OUTPUT :

                      12345  ABCDEF   ABC     12345  ABCDEF   XYZ12345   ABCDEF
                      
                      • If DEF is preceded by ABC, NO replacement occurs

                      • If DEF is NOT preceded by ABC it replaces the string DEF by the string 12345


                      Now, using the same INPUT text :

                      The following regex S/R :

                      FIND (?-is)ABCDEF\K|(DEF)

                      REPLACE ?{1}12345

                      • Detect an empty match, when the DEF string is preceded by the ABC string

                      • Detect some selected text, when the DEF string is NOT preceded by the ABC string

                      But, due to the group, in the final part of the regex and due to the conditional replacement, it would produce this OUTPUT :

                      12345  ABCDEF   ABC     12345  ABCDEF   XYZ12345   ABCDEF
                      

                      As previously :

                      • if DEF is preceded by ABC, NO replacement occurs

                      • if DEF is NOT preceded by ABC it replaces the string DEF by the string 12345


                      Let’s apply this new regex S/R to your problem. Thus, from this regex :

                      FIND (?:<span\b[^>]*?color\s*:\s*black[^>]*>\s*|<p\b[^>]*?color\s*:\s*black[^>]*>\s*<span\b[^>]*>\s*)<code\s*style="background-color:\s*transparent;">(*SKIP)(*F)|<code\s*style="background-color:\s*transparent;">

                      If we simply replace the (*SKIP)(*F) part by \K AND if we put all the right branch of the alternative within a group, this S/R becomes as :

                      FIND (?:<span\b[^>]*?color\s*:\s*black[^>]*>\s*|<p\b[^>]*?color\s*:\s*black[^>]*>\s*<span\b[^>]*>\s*)<code\s*style="background-color:\s*transparent;">\K|(<code\s*style="background-color:\s*transparent;">)

                      REPLACE ?1[REPLACED text]

                      When just searching, the non-interesting matches will be notified as an empty match and the correct matches will be notified as selected text.

                      And if a global replacement occur, with the Replace All button, this regex would just replace the same occurrences as with the (*SKIP)(*F) method !

                      Try against your INPUT text, pasted in a new tab : you should get 2 empty matchs and 4 selected range of characters. And, after replacement you’ll left with four zones [REPLACED text].

                      <html>
                      <p style="font-family: &quot;verdana&quot;; font-size: 18px; color: black; line-height: 18px; text-align: justify; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: cyan;"><span style="font-size: 13.5pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><code style="background-color: transparent;">•••••<b>some text here</b></code></span></p>
                      <span><span style="font-size: 13.5pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; background-color: cyan;"><code style="background-color: transparent;"><b>some text here</b></code></span>
                      
                      
                      <code style="background-color: transparent;">
                      
                      
                      <p style="font-family: &quot;verdana&quot;; font-size: 18px; color: cyan; line-height: 18px; text-align: justify; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: cyan;"><span style="color: black; font-size: 13.5pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><code style="background-color: transparent;">•••••<b>some text here</b></code></span></p>
                      
                      
                      <span><span style="font-size: 13.5pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; background-color: cyan;"><code style="background-color: transparent;"><b>some text here</b></code></span>
                      
                      
                      <p style="font-family: &quot;verdana&quot;; font-size: 18px; color: cyan; line-height: 18px; text-align: justify; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: navy;"><span style="font-size: 13.5pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><code style="background-color: transparent;"><b>some text here</b></code></span></p>
                      </html>
                      

                      Now, it’s not the end of the story ! Imagine that, against the same INPUT text, below :

                      DEF  ABCDEF   ABC     DEF  ABCDEF   XYZDEF   ABCDEF
                      

                      We use this simplified regex S/R :

                      FIND (?-is)ABC\KDEF|(DEF)

                      REPLACE ?{1}12345

                      Note that, this time, the \K is placed before the string DEF

                      So, it would match any string DEF, whatever it’s preceded or NOT by the ABC string

                      But, due to the group, in the final part of the regex and due to the conditional replacement, We would get this new OUTPUT text, after a click on the Replace All button

                      12345  ABC   ABC     12345  ABC   XYZ12345   ABC
                      
                      • if DEF is preceded by ABC, it replaces the string ABCDEF by the string ABC

                      • if DEF is NOT preceded by ABC it replaces the string DEF by the string 12345

                      This S/R is a variant of the previous one which may interest you in some cases !


                      In short, I cannot imagine, presently, other methods than the two above, with (SKIP)(*F) or \K

                      Remember, that the look-arounds structure does not seem appropriate to your style of search !

                      Best Regards,

                      guy038

                      dr ramaanandD 1 Reply Last reply Reply Quote 1
                      • dr ramaanandD
                        dr ramaanand @guy038
                        last edited by

                        @guy038 Oui, merci beaucoup!

                        dr ramaanandD 1 Reply Last reply Reply Quote 0
                        • dr ramaanandD
                          dr ramaanand @dr ramaanand
                          last edited by dr ramaanand

                          This post is deleted!
                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          The Community of users of the Notepad++ text editor.
                          Powered by NodeBB | Contributors