URL расщепление в php - PullRequest
       7

URL расщепление в php

0 голосов
/ 09 июля 2009

У меня есть такой URL:

http://www.w3schools.com/PHP/func_string_str_split.asp

Я хочу разделить этот URL, чтобы получить только часть хоста. Для этого я использую

parse_url($url,PHP_URL_HOST);

возвращает www.w3schools.com. Я хочу получить только «w3schools.com». Есть ли какая-либо функция для этого или я должен сделать это вручную?

Ответы [ 3 ]

6 голосов
/ 09 июля 2009

Есть много способов сделать это. Простая замена - самая быстрая, если вы знаете, что всегда хотите удалить «www.»

$stripped=str_replace('www.', '', $domain);

Замена регулярного выражения позволяет связать это совпадение с началом строки:

$stripped=preg_replace('/^www\./', '', $domain);

Если это всегда первая часть домена, независимо от того, является ли он www, вы можете использовать explode / implode. Хотя его легко прочитать, это самый неэффективный метод:

$parts=explode('.', $domain);
array_shift($parts); //eat first element
$stripped=implode('.', $parts);

регулярное выражение достигает той же цели более эффективно:

$stripped=preg_replace('/^\w+\./', '', $domain);

Теперь вы можете представить, что следующее будет более эффективным, чем приведенное выше регулярное выражение:

$period=strpos($domain, '.');
if ($period!==false)
{
    $stripped=substr($domain,$period+1);
}
else
{
    $stripped=$domain; //there was no period
}

Но я проверил это и обнаружил, что за миллион итераций версия preg_replace постоянно побеждала. Типичные результаты, нормализованные к самому быстрому (поэтому у него есть единичное время 1):

  • Простая str_replace: 1
  • preg_replace с /^\w+\./: 1.494
  • strpos / substr: 1.982
  • взорваться / взорваться: 2,472

Приведенные выше примеры кода всегда удаляют первый компонент домена, поэтому будут отлично работать на доменах, таких как "www.example.com" и "www.example.co.uk", но не на "example.com" или "www. department.example.com». Если вам нужно обрабатывать домены, которые уже могут быть основным доменом или иметь несколько поддоменов (например, «foo.bar.baz.example.com») и хотите уменьшить их до основного домена («example.com») попробуйте следующее. Первый пример в каждом подходе возвращает только два последних компонента домена, поэтому не будет работать с доменами, подобными co.uk.

  • explode

    $parts = explode('.', $domain);
    $parts = array_slice($parts, -2);
    $stripped = implode('.', $parts);
    

    Поскольку explode является самым медленным подходом, нет смысла писать версию, которая обрабатывает "co.uk".

  • регулярное выражение:

    $stripped=preg_replace('/^.*?([^.]+\.[^.]*)$/', '$1', $domain);
    

    Это захватывает последние две части из домена и заменяет полное строковое значение захваченной частью. При наличии нескольких поддоменов все ведущие части удаляются.

    Чтобы работать с доменами, подобными ".co.uk", а также с переменным количеством поддоменов, попробуйте:

    $stripped=preg_replace('/^.*?([^.]+\.(?:[^.]*|[^.]{2}\.[^.]{2}))$/', '$1', $domain);
    
  • ул:

    $end = strrpos($domain, '.') - strlen($domain) - 1;
    $period = strrpos($domain, '.', $end);
    if ($period !== false) {
        $stripped = substr($domain,$period+1);
    } else {
        $stripped = $domain;
    }
    

    Разрешение для доменов co.uk:

    $len = strlen($domain);
    if ($len < 7) {
        $stripped = $domain;
    } else {
        if ($domain[$len-3] === '.' && $domain[$len-6] === '.') {
            $offset = -7;
        } else {
            $offset = -5;
        }
        $period = strrpos($domain, '.', $offset);
        if ($period !== FALSE) {
            $stripped = substr($domain,$period+1);
        } else {
            $stripped = $domain;
        }
    }
    

Реализации на основе регулярных выражений и str могут быть сделаны очень немного быстрее, жертвуя крайними случаями (где компонент основного домена представляет собой одну букву, например, "a.com"):

  • регулярное выражение:

    $stripped=preg_replace('/^.*?([^.]{3,}\.(?:[^.]+|[^.]{2}\.[^.]{2}))$/', '$1', $domain);
    
  • ул:

    $period = strrpos($domain, '.', -7);
    if ($period !== FALSE) {
        $stripped = substr($domain,$period+1);
    } else {
        $stripped = $domain;
    }
    

Хотя поведение изменилось, рейтинг не изменился (большую часть времени). Вот они, время нормализовано до самого быстрого.

  • регулярное выражение нескольких субдоменов: 1
  • .co.uk регулярное выражение (быстро): 1,01
  • .co.uk str (fast): 1.056
  • .co.uk регулярное выражение (правильно): 1,1
  • .co.uk str (правильно): 1.127
  • строковый множественный поддомен: 1,282
  • взрыв нескольких поддоменов: 1.305

Здесь разница во времени настолько мала, что для нее не было ничего необычного. Например, быстрое регулярное выражение .co.uk часто побеждает регулярное регулярное выражение множества субдоменов. Таким образом, точная реализация не должна оказывать заметного влияния на скорость. Вместо этого выберите один на основе простоты и ясности. До тех пор, пока вам не нужно обрабатывать домены .co.uk, это будет подход регулярного выражения с несколькими поддоменами.

0 голосов
/ 09 июля 2009

Вам необходимо удалить любые символы перед первым вхождением символа [.] (Вместе с самим [.]) Тогда и только тогда, когда в возвращаемой строке содержится более 1 вхождения [.].

например, если возвращаемая строка www-139.in.ibm.com, то регулярное выражение должно быть таким, чтобы оно возвращало in.ibm.com, поскольку это будет домен.

Если возвращаемая строка - music.domain.com, то регулярное выражение должно возвращать domain.com

В редких случаях вы получаете доступ к сайту без префикса сервера, то есть вы можете получить доступ к сайту с помощью http://domain.com/pageurl,, в этом случае вы получите домен непосредственно как domain.com, в таком случае регулярное выражение не должно ничего удалять

IMO, это должна быть псевдог логика регулярного выражения, если вы хотите, я могу сформировать регулярное выражение для вас, которое будет включать эти вещи.

0 голосов
/ 09 июля 2009

Вы должны удалить часть субдомена самостоятельно - для этого нет встроенной функции.

// $domain beeing www.w3scools.com
$domain = implode('.', array_slice(explode('.', $domain), -2));

Приведенный выше пример также работает для поддоменов неограниченной глубины, поскольку он всегда будет возвращать последние две части домена (домен и домен верхнего уровня).

Если вы хотите снять только www. , вы можете просто сделать str_replace(), который действительно будет быстрее:

$domain = str_replace('www.', '', $domain);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...