How does the operator (?!) Work in a regular expression?

It seemed to me that I understand how regular expression operators work, but now I'm really confused. In a simplified example, I have two lines:

mail.wow.no-1.com mail.ololo.wow.com 

I want to combine the first, not the second. And I write the regex (simplified version) as follows:

 ^mail\.(.*)(?!\.wow\.com)$ 

And when I run the JS method test on both of these examples, it just returns true (in Sublime 2 regex search, both lines are highlighted, this means that both lines are the same)

I know that I can make a reverse regex that matches the second and make logic depending on this, but I just want to understand how (?!) In regex works and what I'm doing wrong.

Thanks.

+6
source share
4 answers

You need .* Inside the lookahead (and move it before .* Outside the lookahead):

 ^mail(?!.*\.wow\.com)\.(.*)$ 

Otherwise, your view is only checked at the end of the line. And, obviously, there can never be .wow.com at the end of a line. You could just take a look at the beginning of the template now:

 ^(?!.*\.wow\.com)mail\.(.*)$ 

Working demonstration.

This last option is a little less efficient, but I find the templates a little easier to read if the views that affect the entire line are at the beginning of the template.

+8
source

This is a zero width statement . This is a negative outlook.

What he says: in this place - the following cannot come.

So, for example (?!q) means that the letter q cannot follow right now.

+3
source

Do you want to

 ^mail\.(?!.*\.wow\.com$).*$ 

As others have argued, (?!) Is a negative statement with zero width; it does not correspond to the number of characters, but sees in the following characters and ensures that they do not match what is contained in parentheses.

Javascript has copied the regular expression syntax from Perl; they are commonly known as PCRE or Perl-compatible regular expressions; however, Javascript has only views, that is, they see from this point into the future; Perl also has a negative view with zero width, which will work as your original example, in which case it’s easier

 # this is how it could be done in Perl ^mail\..*(?<!\.wow\.com)$ 

However, Javascript decided not to support lookbehinds.

+3
source

Considering this URL is that it is looking for "mail." then as many characters as possible, then checks if there is between this (for example, the end of the line) and the end of the screen if ".wow.com" exists.

 ^mail\.(.*)(?!\.wow\.com)$ 

Instead, reorder to check if ".wow.com" appears after "mail".

 ^mail\.(?!.*\.wow\.com)(.*)$ 
+1
source

Source: https://habr.com/ru/post/951793/


All Articles