Экранирование символов в RegExp выглядит за утверждениями

1

В Regex, чтобы соответствовать сегменту URL, только если не предшествует конкретный родительский сегмент

с учетом ввода

http://example.com/my-slug или http://example.com/my-slug/

требование должно соответствовать

"my-slug"

но не соответствовать

"my-slug"

если предшествуют

"news-events"

Был способен сопоставлять "/my-slug" или "/my-slug/" с помощью утверждений RegExp lookbehind в Chromium с флагом --harmony установленным с RegExp

// why is the '\/' necessary following lookbehind?
let re = /(?<!news-events)\/[^/]+(?=\/$|$)/;

let sources = [
  "http://example.com/my-slug"
, "http://example.com/my-slug/"
, "http://example.com/news-events/my-slug"
];

for (let src of sources) {
  console.log(src.match(re))
}

однако, пытаясь точно сопоставить "my-slug" без предшествующего символа "/", избегая трейлинга "/" в news-event/ RegExp не возвращает такое же совпадение, где соответствует "http://example.com/news-events/my-slug" является "y-slug" когда ожидаемый результат равен null

let re = /(?<!news-events\/)[^/]+(?=\/$|$)/;

let sources = [
  "http://example.com/my-slug"
, "http://example.com/my-slug/"
, "http://example.com/news-events/my-slug"
];

for (let src of sources) {
  console.log(src.match(re))
}

Вопросы:

  • Почему убежал "/" характер не включены как часть RegExp ' назад отрицание утверждения?

  • Как правильно вывести символы или иным образом настроить утверждение RegExp lookbehind, чтобы отрицать полную строку "news-events/" и возвращать ожидаемый результат "my-slug" без необходимости включать \/ перед частью строки, которая должна быть сопоставлена?

Теги:

1 ответ

1
Лучший ответ

Поскольку этот бит регулярного выражения:

[^/]+(?=\/$|$)

совпадает с текстом y-slug (y-slug - несколько символов без косой черты, необязательно сопровождаемый косой чертой, за которым следует конец строки), а y-slug не предшествует news-events/, их действительное совпадение. Поскольку my-slug не соответствует, это также первое действительное соответствие, поэтому возвращается его соответствие.

Вы можете добавить второй, положительный lookbehind, чтобы указать, что любое совпадение должно быть полным сегментом.

let re = /(?<!news-events\/)(?<=\/)[^/]+(?=\/$|$)/;

let sources = [
  "http://example.com/my-slug"
, "http://example.com/my-slug/"
, "http://example.com/news-events/my-slug"
];

for (let src of sources) {
  console.log(src.match(re))
}
  • 0
    Почему RegExp , который не возвращает ожидаемый результат, когда \/ включен в lookbehind [^/]+(?=\/$|$) Соответствует "y-slug" а не "my-slug" ?
  • 0
    @ guest271314: Согласны ли вы с тем, что "y-slug" соответствует [^/]+(?=\/$|$) ?
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню