Страницы

Поиск по вопросам

понедельник, 10 февраля 2020 г.

Как заменить абсолютный адрес на относительный регулярным выражением?

#javascript #регулярные_выражения #url


Написал вот такой тест

// the domain is 'test.dev'
function test (str) {
    rep = str.replace(/^(?:https?:)?\/\/test\.dev(?:$|\/)/, "/");
    console.log('Was: ' + str + '\nNow: ' + rep);
}
test("http://test.dev/path?query=string");
test("https://test.dev/");
test("//test.dev");
test("//test.dev/?query=string");


, который работает и выдает

Was: http://test.dev/path?query=string
Now: /path?query=string

Was: https://test.dev/
Now: /

Was: //test.dev
Now: /

Was: //test.dev/?query=string
Now: /?query=string


Но ссылка может быть еще и такого вида (без слэша перед началом query string): //test.dev?query=string,
и тогда регулярка выше не срабатывает. Как бы в нее попроще этот вопросительный знак
воткнуть?  

Из //test.dev?query=string должно получиться /?query=string.

Придется дополнить вопрос. Исходные ссылки могут быть не только на test.dev, но и
на другие сайты (например, test.devil). Такие ссылки нельзя превратить в относительные,
точнее можно, но это не будет иметь смысла по отношению к сайту test.dev, поэтому они
должны оставаться как есть.
    


Ответы

Ответ 1



Предлагаю заменить rep = str.replace(/^(?:https?:)?\/\/test\.dev(?:$|\/)/, "/"); на rep = str.replace(/^(?:https?:)?\/\/test\.dev(?:$|\/|(\?))/, "/$1"); ^^^^ Добавив захватывающую подмаску (\?) в качестве ещё одной альтернативы в незахватывающую группу, можно отловить знак вопроса, а потом с помощью обратной ссылки $1 в шаблоне замены восстановить его в получаемой строке. function test (str) { rep = str.replace(/^(?:https?:)?\/\/test\.dev(?:$|\/|(\?))/, "/$1"); console.log('Was: ' + str + '\nNow: ' + rep); } test("http://test.dev/path?query=string"); test("https://test.dev/"); test("//test.dev"); test("//test.dev/?query=string"); test("//test.dev?query=string"); // /?query=string

Ответ 2



Достаточно просто добавить * после второй группы. Это будет означать, что после .dev должно быть ноль или больше слэшей, если образно. В итоге получается так: rep = str.replace(/^(?:https?:)?\/\/test\.dev(?:$|\/*)/, "/") P.S. ели еще не пользуетесь подобными вещами, советую посмотреть сервис regex101 - удобно и с наглядными пояснениями элементов

Ответ 3



Можно просто разделить строку по домену и взять правую часть. var domain = 'example.org'; [ 'http://example.org/some/path?key=value', 'https://example.org/some/path?key=value', 'http://example.org/?key=value', 'http://example.org?вполне_корректная_относительная_ссылка', 'http://example.org/', '//example.org/without/proto' ].forEach(function(url) { console.log(url.split(domain)[1]); }); // Так же можно проверить наличие корректного домена let list = [ 'http://example.organ/?key=value', 'http://example.com/', 'http://example.org/' ].map(url => { if (url.split('/')[2] !== domain) return url; return url.split(domain)[1] }); console.log(list);

Комментариев нет:

Отправить комментарий