Negative lookbehind regular expression not working on Notepad++
-
Peter’s last point (which you missed) was that lookaheads are best done with native regex syntax, because it is more obvious that way.
And he probably would have confused you less if he had left out
(negative or positive)
from his sentence; doing that doesn’t change the meaning. -
Hello, @peterjones and All,
OK. I going to prepare a blog post regarding the
(*SKIP)(*F)
feature !However, be patient because I’ll try, first :
-
To find out some other pertinent examples from various regex sites
-
To propose alternatives to the
(*SKIP)(*F)
syntax when it’s possible !
BR
guy038
-
-
@guy038 please create the blog to show how to use the
(*SKIP)(*FAIL)
regular expression, not an alternative to it. @PeterJones may be able to create an alternative to it. If @PeterJones wants to still use his method for what I have typed as my block for testing, he can do it in 2 parts; first using the regular expression,(<span\b[^>]*?color\s*:\s*black[^>]*>\s*|<p\b[^>]*?color\s*:\s*black[^>]*>\s*<span\b[^>]*>\s*)\K(<code\s*style="background-color:\s*transparent;">)
in the find field and a unique string (say for example, a unique name like, “Czeslawski”) in the replace field, he can replace the<code\s*style="background-color:\s*transparent;">
with that unique string. Then he can do what is needed to the other strings of<code\s*style="background-color:\s*transparent;">
and then again replace the unique string (“Czeslawski” in this case) with<code\s*style="background-color:\s*transparent;">
. If it is something simple, this example should be sufficient: https://stackoverflow.com/questions/17286667/regular-expression-using-negative-lookbehind-not-working-in-notepad -
Hello, @dr-ramaanand,
When I said :
To propose alternatives to the
(*SKIP)(*F)
syntax when it’s possible !I’m not talking about a work-around, using a several-steps regex, but, indeed, other direct regexes, without the
(*SKIP)(*F)
syntax, which are, sometimes, even shorter !You’ll understand what I mean., sooner !
Best Regards,
guy038
-
@guy038 I will understand it only after you post that regular expression (RegEx) here
-
This post is deleted! -
Hello, @peterjones and All,
Peter, Done ! Refer to :
I also added a link to this post in your
FAQ: Generic Regular Expression (regex) Formulas
post.Best Regards,
guy038
-
@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 -
@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.
-
@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.
-
@guy038 The answer by User Doqnach mentioned at https://stackoverflow.com/questions/25563891/variable-length-look-behind can be used as an example.
-
@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: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.
-
@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 -
-
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
stringAfter the replacement, we get this OUTPUT :
12345 ABCDEF ABC 12345 ABCDEF XYZ12345 ABCDEF
-
If
DEF
is preceded byABC
, NO replacement occurs -
If
DEF
is NOT preceded byABC
it replaces the stringDEF
by the string12345
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 theABC
string -
Detect some selected text, when the
DEF
string is NOT preceded by theABC
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 byABC
, NO replacement occurs -
if
DEF
is NOT preceded byABC
it replaces the stringDEF
by the string12345
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 and4
selected range of characters. And, after replacement you’ll left with four zones[REPLACED text]
.<html> <p style="font-family: "verdana"; 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: "Verdana","sans-serif";"><code style="background-color: transparent;">•••••<b>some text here</b></code></span></p> <span><span style="font-size: 13.5pt; font-family: "Verdana","sans-serif"; background-color: cyan;"><code style="background-color: transparent;"><b>some text here</b></code></span> <code style="background-color: transparent;"> <p style="font-family: "verdana"; 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: "Verdana","sans-serif";"><code style="background-color: transparent;">•••••<b>some text here</b></code></span></p> <span><span style="font-size: 13.5pt; font-family: "Verdana","sans-serif"; background-color: cyan;"><code style="background-color: transparent;"><b>some text here</b></code></span> <p style="font-family: "verdana"; 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: "Verdana","sans-serif";"><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 stringDEF
So, it would match any string
DEF
, whatever it’s preceded or NOT by theABC
stringBut, 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
button12345 ABC ABC 12345 ABC XYZ12345 ABC
-
if
DEF
is preceded byABC
, it replaces the stringABCDEF
by the stringABC
-
if
DEF
is NOT preceded byABC
it replaces the stringDEF
by the string12345
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
-
-
@guy038 Oui, merci beaucoup!