с учетом ввода
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"
без необходимости включать \/
перед частью строки, которая должна быть сопоставлена?
Поскольку этот бит регулярного выражения:
[^/]+(?=\/$|$)
совпадает с текстом 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))
}
RegExp
, который не возвращает ожидаемый результат, когда\/
включен в lookbehind[^/]+(?=\/$|$)
Соответствует"y-slug"
а не"my-slug"
?"y-slug"
соответствует[^/]+(?=\/$|$)
?