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

возьмите строку, такую как:

В C#: Как добавить "кавычки" вокруг строки в списке строк с разделителями-запятыми?

и преобразовать его в:

in-c-how-do-i-add-quotes-around-string-in-a-comma-delimited-list-of-strings

требования:

  • отделить каждое слово тире и удалить все знаки препинания (с учетом того, что не все слова разделены пространства.)
  • функция принимает максимальную длину и получает все маркеры ниже этой максимальной длины. Пример: ToSeoFriendly("hello world hello world", 14) возвращает "hello-world"
  • все слова переводятся в нижний регистр.

на отдельном примечании, должна ли быть минимальная длина?

12 ответов


вот мое решение в C#

private string ToSeoFriendly(string title, int maxLength) {
    var match = Regex.Match(title.ToLower(), "[\w]+");
    StringBuilder result = new StringBuilder("");
    bool maxLengthHit = false;
    while (match.Success && !maxLengthHit) {
        if (result.Length + match.Value.Length <= maxLength) {
            result.Append(match.Value + "-");
        } else {
            maxLengthHit = true;
            // Handle a situation where there is only one word and it is greater than the max length.
            if (result.Length == 0) result.Append(match.Value.Substring(0, maxLength));
        }
        match = match.NextMatch();
    }
    // Remove trailing '-'
    if (result[result.Length - 1] == '-') result.Remove(result.Length - 1, 1);
    return result.ToString();
}

Я бы следовал этим шагам:

  1. преобразовать строку в нижний регистр
  2. замените нежелательные символы дефисами
  3. заменить несколько дефисов на один дефис (не обязательно как preg_replace() вызов функции уже предотвращает несколько дефисов)
  4. удалить hypens в начале и конце, если надо
  5. при необходимости обрезать от последнего дефиса до позиции x до конца

Так, все вместе в функции (PHP):

function generateUrlSlug($string, $maxlen=0)
{
    $string = trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($string)), '-');
    if ($maxlen && strlen($string) > $maxlen) {
        $string = substr($string, 0, $maxlen);
        $pos = strrpos($string, '-');
        if ($pos > 0) {
            $string = substr($string, 0, $pos);
        }
    }
    return $string;
}

C#

public string toFriendly(string subject)
{
    subject = subject.Trim().ToLower();
    subject = Regex.Replace(subject, @"\s+", "-");
    subject = Regex.Replace(subject, @"[^A-Za-z0-9_-]", "");
    return subject;
}

вот решение для php:

function make_uri($input, $max_length) {
  if (function_exists('iconv')) {  
    $input = @iconv('UTF-8', 'ASCII//TRANSLIT', $input);  
  }

  $lower = strtolower($input);


  $without_special = preg_replace_all('/[^a-z0-9 ]/', '', $input);
  $tokens = preg_split('/ +/', $without_special);

  $result = '';

  for ($tokens as $token) {
    if (strlen($result.'-'.$token) > $max_length+1) {
      break;
    }

    $result .= '-'.$token;       
  }

  return substr($result, 1);
}

использование:

echo make_uri('In C#: How do I add "Quotes" around string in a ...', 500);

Если вам не нужно, чтобы URI были типируемыми, они не должны быть маленькими. Но вы должны указать максимум, чтобы URL-адреса хорошо работали с прокси и т. д.


лучший вариант:

function Slugify($string)
{
    return strtolower(trim(preg_replace(array('~[^0-9a-z]~i', '~-+~'), '-', $string), '-'));
}

решение в Perl:

my $input = 'In C#: How do I add "Quotes" around string in a comma delimited list of strings?';

my $length = 20;
$input =~ s/[^a-z0-9]+/-/gi;
$input =~ s/^(.{1,$length}).*/\L/;

print "$input\n";

сделано.


решение в скорлупе:

echo 'In C#: How do I add "Quotes" around string in a comma delimited list of strings?' | \
    tr A-Z a-z | \
    sed 's/[^a-z0-9]\+/-/g;s/^\(.\{1,20\}\).*//'

это близко к тому, как переполнение стека создает слизней:

public static string GenerateSlug(string title)
{
    string slug = title.ToLower();
    if (slug.Length > 81)
      slug = slug.Substring(0, 81);
    slug = Regex.Replace(slug, @"[^a-z0-9\-_\./\ ]+", "");
    slug = Regex.Replace(slug, @"[^a-z0-9]+", "-");

    if (slug[slug.Length - 1] == '-')
      slug = slug.Remove(slug.Length - 1, 1);
    return slug;
}

немного более чистый способ сделать это в PHP, по крайней мере:

function CleanForUrl($urlPart, $maxLength = null) {
    $url = strtolower(preg_replace(array('/[^a-z0-9\- ]/i', '/[ \-]+/'), array('', '-'), trim($urlPart)));
    if ($maxLength) $url = substr($url, 0, $maxLength);
    return $url;
}

мог бы также сделать trim() в начале, так что меньше обрабатывать позже, и полная замена выполняется в preg_replace().

Thxs в cg для придумывания большей части этого:каков наилучший способ очистить строку для размещения в URL-адресе, например, имя вопроса на SO?


в динамическом URL эти идентификаторы передаются через строку запроса скрипту, который ... в качестве разделяющего символа, потому что большинство поисковых систем рассматривают тире как a ... NET: руководство разработчика по SEO также охватывает эти три дополнительных метода поисковая оптимизация


еще один сезон, еще одна причина для выбора Ruby :)

def seo_friendly(str)
  str.strip.downcase.gsub /\W+/, '-'
end

вот и все.


в python, (если django установлен, даже если вы используете другую структуру.)

from django.template.defaultfilters import slugify
slugify("In C#: How do I add "Quotes" around string in a comma delimited list of strings?")