Javascript, чтобы соответствовать строке, которая заканчивается некоторыми символами, но не с определенной комбинацией этих

Скажем, используя Javascript, я хочу совместить строку, которая заканчивается на [abcde]*, но не с abc.

Поэтому регулярное выражение должно соответствовать xxxa, xxxbc, xxxabd, но не xxxabc.

Я совершенно смущен.

Изменить: По какой-то причине мне нужно использовать регулярное выражение, я не могу что-то сделать if (str.endsWith("abc"))

Ответ 1

Решение прост: используйте отрицательный просмотр:

(?!.*abc$)

Это означает, что строка не заканчивается на abc.

Вы упомянули, что вам также нужна строка, заканчивающаяся [abcde]*, но * означает, что она необязательна, поэтому xxx соответствует. Я предполагаю, что вы действительно хотите [abcde]+, что также просто означает, что он должен заканчиваться на [abcde]. В этом случае утверждения следующие:

(?=.*[abcde]$)(?!.*abc$)

Смотрите regular-expressions.info для учебных пособий по положительным и отрицательным образам.


Я не хотел давать реальное регулярное выражение Javascript, так как я не знаком с языком (хотя я был уверен, что утверждения, если они будут поддерживаться, будут работать - согласно regular-expressions.info, Javascript поддерживает положительные и отрицательные образы). Благодаря комментариям Pointy и Alan Moore, я думаю, что правильное регулярное выражение Javascript таково:

var regex = /^(?!.*abc$).*[abcde]$/;

Обратите внимание, что эта версия (с учетом Алана Мура) больше не нуждается в положительном взгляде. Он просто соответствует .*[abcde]$, но сначала утверждает ^(?!.*abc$).

Ответ 2

Или вопрос не определен правильно, или все не видят простого ответа.

var re = /abc$/;

!re.test("xxxa");    // pass
!re.test("xxxbc");   // pass
!re.test("xxxabd");  // pass
!re.test("xxxabc");  // fail

Все они заканчиваются на /[abcde]*/

Ответ 3

Во-первых, обратите внимание, что каждая строка заканчивается на [abcde]*, так как это допускает нулевую ширину. Таким образом, мы действительно просто искали регулярное выражение, которое соответствует строкам, которые не заканчиваются на abc. Легко.

([^c]|[^b]c|[^a]bc)$

Что-то, что не c, то, что не b, за которым следует c, или что-то, что не a, за которым следует bc, и какой бы вариант они ни были, а затем конец строки.

Ответ 4

Просто хочу сказать @maček, что вы отвечаете просто и ясно с помощью ! в начале Но я действительно хотел, чтобы оператор не был внутри regexp, поэтому я мог бы использовать его, например: Array::some, Array::filter, Array::find, Array::findIndex и без необходимости создавать функцию или цикл wile

Вот пример:

var items = ["ja", "ka", "mf", "bg", "vb", "b"]
var regex = /^((?!a$|b$).)*$/; // match a string that doesn't end with a or b

var matched = items.filter(RegExp.prototype.test, regex);

alert(matched); // result: ["mf", "bg"]

Ответ 5

Хм...

var regex = /(ab[abde]|[abcde])$/; // wrong

может быть? ждать нет; держись:

var regex = /(ab[abde]|([^a].|.[^b])[abcde]|\b.?[abcde])$/;

Итак, "ab" следует за "a" , "b", "d" или "e" ; или любой двухсимвольной последовательности, где первый символ не является "а", или второй символ не "b", а затем "a" через "e" ; или любую границу слова, за которой следует любой символ (возможно), за которым следует "a" через "e" . Последнее предложение касается коротких строк; это своего рода обман, но в этом случае он работает.