Negative Expression Regular Expression

I want all lines to end with ".htm" if they don't end with "foo.htm". I’m generally decent with regular expressions, but negative views will puzzle me. Why is this not working?

/(?!foo)\.htm$/i.test("/foo.htm"); // returns true. I want false. 

What should i use instead? I think I need the expression "negative look behind " (if JavaScript supports such a thing that I know about, it is not).

+47
javascript regex regex-lookarounds
Jul 27 '11 at 10:16
source share
6 answers

The problem is pretty simple. This will do it:

/^(?!.*foo\.htm$).*\.htm$/i

+72
Jul 27 2018-11-23T00:
source share

What you are describing (your intention) is a negative look, and Javascript does not support feedback.

A look ahead is to look at the character on which they are placed β€”β€” and you placed it before . . So what do you actually say β€œanything ending in .htm if the first three characters starting at that position ( .ht ) are not foo ”, which is always true.

Typically, replacing negative back delays should fit more than you need and extract only the part that you really need. These are hacks, and depending on your exact situation, you can probably come up with something else, but something like this:

 // Checks that the last 3 characters before the dot are not foo: /(?!foo).{3}\.htm$/i.test("/foo.htm"); // returns false 
+14
Jul 27 '11 at 22:20
source share

As already mentioned, JavaScript does not support negative statements in reverse order.

But you can use workaroud:

 /(foo)?\.htm$/i.test("/foo.htm") && RegExp.$1 != "foo"; 

This will match everything that ends in .htm , but it will save "foo" in RegExp.$1 if it matches foo.htm , so you can handle it separately.

+2
Jul 27 '11 at 10:25
source share

As Renesis is mentioned, "lookbehind" is not supported in JavaScript, so maybe just use two regular expressions in combination:

 !/foo\.htm$/i.test(teststring) && /\.htm$/i.test(teststring) 
+2
Jul 27 '11 at 10:26
source share

String.prototype.endsWith ( ES6 )

 console.log( /* !(not)endsWith */ !"foo.html".endsWith("foo.htm"), // true !"barfoo.htm".endsWith("foo.htm"), // false (here you go) !"foo.htm".endsWith("foo.htm"), // false (here you go) !"test.html".endsWith("foo.htm"), // true !"test.htm".endsWith("foo.htm") // true ); 
+1
Mar 22 '16 at 22:33
source share

You can imitate a negative lookbehind with something like /(.|..|.*[^f]..|.*f[^o].|.*fo[^o])\.htm$/ , but a programmatic approach would be better.

0
Jul 27 2018-11-22T00:
source share



All Articles