Подтвердить что ты не робот

Негативное выражение Обычное выражение

Я хочу, чтобы все строки заканчивались на ".htm", если они не заканчиваются на "foo.htm". Я вообще порядочный с регулярными выражениями, но негативные взгляды меня озадачат. Почему это не работает?

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

Что я должен использовать вместо этого? Я думаю, что мне нужно выражение "negative look behind" (если JavaScript поддерживает такую ​​вещь, о которой я знаю, это не так).

4b9b3361

Ответ 1

Проблема довольно проста. Это сделает это:

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

Ответ 2

То, что вы описываете (ваше намерение), является негативным взглядом, а Javascript не поддерживает обратную связь.

Взгляд вперед - смотреть на персонажа, на котором они размещены -— и вы разместили его до .. Итак, что вы на самом деле говорите "что-либо, заканчивающееся на .htm, если первые три символа, начинающиеся с этой позиции (.ht), не являются foo", что всегда верно.

Обычно замена отрицательных обратных задержек должна соответствовать большему, чем вам нужно, и извлекать только ту часть, которая вам действительно нужна. Это хаки, и в зависимости от вашей точной ситуации вы, вероятно, можете придумать что-то еще, но что-то вроде этого:

// Checks that the last 3 characters before the dot are not foo:
/(?!foo).{3}\.htm$/i.test("/foo.htm"); // returns false 

Ответ 3

Как уже упоминалось, JavaScript не поддерживает отрицательные утверждения в обратном порядке.

Но вы можете использовать workaroud:

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

Это будет соответствовать всем, что заканчивается на .htm, но оно сохранит "foo" в RegExp.$1, если оно соответствует foo.htm, поэтому вы можете обрабатывать его отдельно.

Ответ 4

Как упоминается Renesis, "lookbehind" не поддерживается в JavaScript, поэтому, возможно, просто используйте два регулярных выражения в комбинации:

!/foo\.htm$/i.test(teststring) && /\.htm$/i.test(teststring)

Ответ 5

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

);

Ответ 6

Вы можете подражать негативному lookbehind с чем-то вроде /(.|..|.*[^f]..|.*f[^o].|.*fo[^o])\.htm$/, но программный подход будет лучше.