Как отрезать домен из строки

160
22 мая 2019, 15:10
https://test.ru/test-url/other
http://test.ru/test-url
//test.ru/test-url
https://www.test.ru/test-url/other
http://www.test.ru/test-url
www.test.ru/test-url/other
test.ru/test-url
testru/test-url/other

Надо получить test-url/other

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

Answer 1

В вашем случае достаточно нормализовать URI и потом отрезать все до первого слыша. Ну или просто взять и отрезать все от первого слыша, убрав предварительно разделитель протокола:

// Сама функция
function removeDomain($url) {
    $withoutProtocolDelimiter = str_replace('//', '', $url);
    return substr($withoutProtocolDelimiter, strpos($withoutProtocolDelimiter, '/') + 1);
}
// Проверочный массив
$array = [
    "https://test.ru/test-url",
    "http://test.ru/test-url",
    "//test.ru/test-url",
    "https://www.test.ru/test-url",
    "http://www.test.ru/test-url",
    "www.test.ru/test-url",
    "test.ru/test-url",
    "testru/test-url",
    "ftp://test.ru/test-url",
    "smb://test.ru/test-url",
    "/test-url",
];
// Проверка
foreach($array as $url) {
    echo assert(removeDomain($url) === 'test-url'), PHP_EOL;
}

Незачем использовать регулярки, там, где они не нужны. Этот код будет работать быстрее и обработает даже результаты типа ftp://test.ru/test-url или smb://test.ru/test-url. И код настолько простой, что в нем разобраться и его поддерживать может даже джуниор.

Answer 2

Используйте регулярки, вот например которая подойдет вам:

/^(https?:)?(\/\/)?[^\/]+(.+)$/m

Эта регулярка вернет "без" первого слэша

/^(https?:)?(\/\/)?[^\/]+\/(.+)$/m

Как использовать:

$InStr = "https://test.ru/test-url"."\r\n".
         "http://test.ru/test-url";
preg_match_all('/^(https?:)?(\/\/)?[^\/]+(.+)$/m',$InStr,$mathes);
print_r($matches);
foreach($matches as $val)
echo $val[3]

Чуть не забыл, пример : https://regex101.com/r/kqm48P/1/

Answer 3

Может просто url нормализовать под parse_url?

$array = [
    "https://test.ru/test-url",
    "http://test.ru/test-url",
    "//test.ru/test-url",
    "https://www.test.ru/test-url",
    "http://www.test.ru/test-url",
    "www.test.ru/test-url",
    "test.ru/test-url",
    "testru/test-url",
    "ftp://test.ru/test-url",
    "smb://test.ru/test-url",
    "test.ru/test/url/html.php",
];
foreach($array as $url) {
    echo '<li>'.parse_url( strpos($url,'//')!==false ? $url : '//'.$url, PHP_URL_PATH);
}

Чуть проще для восприятия

foreach($array as $url) {
    if( strpos($url,'//') === false ) $url='//'.$url;
    echo '<li>'.parse_url($url, PHP_URL_PATH);
}
READ ALSO
Как пишутся сложные парсеры на php?

Как пишутся сложные парсеры на php?

Не является проблемой подменить заголовки, реферер, уникальный ип, куки

155
Запретить создание объектов вне класса

Запретить создание объектов вне класса

структура директории: libs - каталог indexphp - точка входа В каталоге libs лежит файл test

149
Как заполнить ассоциативный массив

Как заполнить ассоциативный массив

Подскажите как в PHP через foreach заполнить ассоциативный массив вида

168
Расстояние между всеми точками массива

Расстояние между всеми точками массива

Проинициализировать два массива, которые задают n точек координатами (X, Y) в двумерном пространствеОписать функцию, которая найдет расстояния...

123