스택 오버플로는 SEO 친화적 인 URL을 어떻게 생성합니까?
좋은 정규 표현식 이나 제목을 취하는 다른 프로세스 는 무엇입니까?
제목을 스택 오버플로와 같은 URL의 일부로 변경하려면 어떻게합니까?
그것을
how-do-you-change-a-title-to-be-part-of-the-url-like-stack-overflow
스택 오버플로의 SEO 친화적 인 URL에 사용됩니까?
내가 사용하는 개발 환경은 Ruby on Rails 이지만 다른 플랫폼 별 솔루션 (.NET, PHP, Django ) 이 있다면 그 역시보고 싶습니다.
나는 (또는 다른 독자) 다른 플랫폼에서 같은 문제를 겪을 것이라고 확신합니다.
사용자 지정 경로를 사용하고 있으며 주로 모든 특수 문자가 제거되고 모두 소문자이며 모든 공백이 바뀐 문자열을 변경하는 방법을 알고 싶습니다.
여기 우리가하는 방법이 있습니다. 언뜻보기에 알고있는 것보다 더 많은 엣지 조건이있을 수 있습니다.
이것은 두 번째 버전으로 5 배 더 많은 성능을 제공합니다 (그리고 벤치 마크했습니다). 이 함수는 페이지 당 수백 번 호출 될 수 있기 때문에 최적화 할 것이라고 생각했습니다.
/// <summary>
/// Produces optional, URL-friendly version of a title, "like-this-one".
/// hand-tuned for speed, reflects performance refactoring contributed
/// by John Gietzen (user otac0n)
/// </summary>
public static string URLFriendly(string title)
{
if (title == null) return "";
const int maxlen = 80;
int len = title.Length;
bool prevdash = false;
var sb = new StringBuilder(len);
char c;
for (int i = 0; i < len; i++)
{
c = title[i];
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
{
sb.Append(c);
prevdash = false;
}
else if (c >= 'A' && c <= 'Z')
{
// tricky way to convert to lowercase
sb.Append((char)(c | 32));
prevdash = false;
}
else if (c == ' ' || c == ',' || c == '.' || c == '/' ||
c == '\\' || c == '-' || c == '_' || c == '=')
{
if (!prevdash && sb.Length > 0)
{
sb.Append('-');
prevdash = true;
}
}
else if ((int)c >= 128)
{
int prevlen = sb.Length;
sb.Append(RemapInternationalCharToAscii(c));
if (prevlen != sb.Length) prevdash = false;
}
if (i == maxlen) break;
}
if (prevdash)
return sb.ToString().Substring(0, sb.Length - 1);
else
return sb.ToString();
}
대체 된 코드의 이전 버전 (기능적으로 동일하지만 5 배 빠름)을 보려면이 게시물의 개정 내역을 확인하십시오 (날짜 링크 클릭).
또한 RemapInternationalCharToAscii
메소드 소스 코드는 여기 에서 찾을 수 있습니다 .
여기에 Jeff의 코드 버전이 있습니다. 다음과 같이 변경했습니다.
- 하이픈은 추가 할 수있는 방식으로 추가 된 다음 문자열의 마지막 문자이므로 제거해야합니다. 즉,“my-slug-”를 원하지 않습니다. 이것은이 경우에이를 제거하기위한 추가 문자열 할당을 의미합니다. 지연 하이픈 으로이 문제를 해결했습니다. 내 코드를 Jeff의 코드와 비교하면 논리가 따르기 쉽습니다.
- 그의 접근 방식은 순전히 조회 기반이며 스택 오버플로를 연구하는 동안 예제에서 찾은 많은 문자를 놓쳤습니다. 이 문제를 해결하기 위해 먼저 정규화 단계 (Meta Stack Overflow question 비 US-ASCII 문자가 전체 (프로필) URL에서 삭제됨)에 언급 된 AKA 데이터 정렬)를 수행 한 다음 허용 가능한 범위를 벗어난 문자는 무시합니다. 이것은 대부분의 시간에 작동합니다 ...
- ... 그렇지 않은 경우 조회 테이블을 추가해야했습니다. 위에서 언급했듯이 일부 문자는 정규화 할 때 낮은 ASCII 값으로 매핑되지 않습니다. 이 항목을 삭제하는 대신 구멍으로 가득 찬 예외 목록을 수동으로 얻었지만 아무것도 아닌 것보다 낫습니다. 정규화 코드는 스택 오버플로 질문에서 Jon Hanna의 위대한 게시물에서 영감을 얻었습니다 . 문자열에서 악센트를 제거하는 방법은 무엇입니까? .
사례 변환도 이제 선택 사항입니다.
public static class Slug { public static string Create(bool toLower, params string[] values) { return Create(toLower, String.Join("-", values)); } /// <summary> /// Creates a slug. /// References: /// http://www.unicode.org/reports/tr15/tr15-34.html /// https://meta.stackexchange.com/questions/7435/non-us-ascii-characters-dropped-from-full-profile-url/7696#7696 /// https://stackoverflow.com/questions/25259/how-do-you-include-a-webpage-title-as-part-of-a-webpage-url/25486#25486 /// https://stackoverflow.com/questions/3769457/how-can-i-remove-accents-on-a-string /// </summary> /// <param name="toLower"></param> /// <param name="normalised"></param> /// <returns></returns> public static string Create(bool toLower, string value) { if (value == null) return ""; var normalised = value.Normalize(NormalizationForm.FormKD); const int maxlen = 80; int len = normalised.Length; bool prevDash = false; var sb = new StringBuilder(len); char c; for (int i = 0; i < len; i++) { c = normalised[i]; if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { if (prevDash) { sb.Append('-'); prevDash = false; } sb.Append(c); } else if (c >= 'A' && c <= 'Z') { if (prevDash) { sb.Append('-'); prevDash = false; } // Tricky way to convert to lowercase if (toLower) sb.Append((char)(c | 32)); else sb.Append(c); } else if (c == ' ' || c == ',' || c == '.' || c == '/' || c == '\\' || c == '-' || c == '_' || c == '=') { if (!prevDash && sb.Length > 0) { prevDash = true; } } else { string swap = ConvertEdgeCases(c, toLower); if (swap != null) { if (prevDash) { sb.Append('-'); prevDash = false; } sb.Append(swap); } } if (sb.Length == maxlen) break; } return sb.ToString(); } static string ConvertEdgeCases(char c, bool toLower) { string swap = null; switch (c) { case 'ı': swap = "i"; break; case 'ł': swap = "l"; break; case 'Ł': swap = toLower ? "l" : "L"; break; case 'đ': swap = "d"; break; case 'ß': swap = "ss"; break; case 'ø': swap = "o"; break; case 'Þ': swap = "th"; break; } return swap; } }
자세한 내용, 단위 테스트 및 Facebook 의 URL 체계가 스택 오버플로보다 조금 더 똑똑한 이유에 대한 설명을 보려면 블로그에서이 버전을 확장했습니다 .
URL 을 처리 할 컨트롤러를 URL 을 가리 키도록 사용자 지정 경로를 설정하려고 합니다. Ruby on Rails를 사용하고 있으므로 라우팅 엔진 사용에 대한 소개 입니다.
Ruby에서는 이미 알고있는 정규식이 필요하며 다음과 같이 사용할 정규식이 있습니다.
def permalink_for(str)
str.gsub(/[^\w\/]|[!\(\)\.]+/, ' ').strip.downcase.gsub(/\ +/, '-')
end
이 JavaScript 함수를 사용 하여 슬러그의 정보를 생성 할 수 있습니다 (이것은 Django 기반으로 / 복사 됨 ).
function makeSlug(urlString, filter) {
// Changes, e.g., "Petty theft" to "petty_theft".
// Remove all these words from the string before URLifying
if(filter) {
removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
"is", "in", "into", "like", "of", "off", "on", "onto", "per",
"since", "than", "the", "this", "that", "to", "up", "via", "het", "de", "een", "en",
"with"];
}
else {
removelist = [];
}
s = urlString;
r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
s = s.replace(r, '');
s = s.replace(/[^-\w\s]/g, ''); // Remove unneeded characters
s = s.replace(/^\s+|\s+$/g, ''); // Trim leading/trailing spaces
s = s.replace(/[-\s]+/g, '-'); // Convert spaces to hyphens
s = s.toLowerCase(); // Convert to lowercase
return s; // Trim to first num_chars characters
}
좋은 측정을 위해 여기에 WordPress의 PHP 기능이 있습니다 ... WordPress는 멋진 링크를 사용하는 가장 인기있는 플랫폼 중 하나라고 생각합니다.
sanitize_title_with_dashes ($ title) 함수 { $ title = strip_tags ($ 제목); // 이스케이프 된 옥텟을 유지합니다. $ title = preg_replace ( '| % ([a-fA-F0-9] [a-fA-F0-9]) |', '--- $ 1 ---', $ title); // 8 진수의 일부가 아닌 퍼센트 부호를 제거합니다. $ title = str_replace ( '%', '', $ title); // 옥텟을 복원합니다. $ title = preg_replace ( '| --- ([a-fA-F0-9] [a-fA-F0-9]) --- |', '% $ 1', $ title); $ title = remove_accents ($ title); if (seems_utf8 ($ title)) { if (function_exists ( 'mb_strtolower')) { $ title = mb_strtolower ($ 제목, 'UTF-8'); } $ title = utf8_uri_encode ($ title, 200); } $ title = strtolower ($ 제목); $ title = preg_replace ( '/&.+?;/', '', $ title); // 엔티티 죽이기 $ title = preg_replace ( '/ [^ % a-z0-9 _-] /', '', $ title); $ title = preg_replace ( '/ \ s + /', '-', $ title); $ title = preg_replace ( '|-+ |', '-', $ title); $ title = trim ($ title, '-'); $ title를 반환; }
이 기능과 일부 지원 기능은 wp-includes / formatting.php에서 찾을 수 있습니다.
Rails Edge를 사용하는 경우 Inflector.parametrize 를 사용할 수 있습니다 . 다음은 설명서의 예입니다.
class Person
def to_param
"#{id}-#{name.parameterize}"
end
end
@person = Person.find(1)
# => #<Person id: 1, name: "Donald E. Knuth">
<%= link_to(@person.name, person_path(@person)) %>
# => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
당신은 레일의 이전 버전에서 악센트 (éphémère)로 이국적인 문자를 처리 할 필요 또한, 당신은 혼합 사용할 수 있습니다 PermalinkFu 및 DiacriticsFu를 :
DiacriticsFu::escape("éphémère")
=> "ephemere"
DiacriticsFu::escape("räksmörgås")
=> "raksmorgas"
Ruby on Rails에 익숙하지 않지만 다음은 PHP 코드입니다. 유용한 경우 Ruby on Rails로 매우 빠르게 번역 할 수 있습니다.
$sURL = "This is a title to convert to URL-format. It has 1 number in it!";
// To lower-case
$sURL = strtolower($sURL);
// Replace all non-word characters with spaces
$sURL = preg_replace("/\W+/", " ", $sURL);
// Remove trailing spaces (so we won't end with a separator)
$sURL = trim($sURL);
// Replace spaces with separators (hyphens)
$sURL = str_replace(" ", "-", $sURL);
echo $sURL;
// outputs: this-is-a-title-to-convert-to-url-format-it-has-1-number-in-it
이게 도움이 되길 바란다.
Ruby 나 Rails는별로 없지만 Perl에서는 다음과 같이합니다.
my $title = "How do you change a title to be part of the url like Stackoverflow?";
my $url = lc $title; # Change to lower case and copy to URL.
$url =~ s/^\s+//g; # Remove leading spaces.
$url =~ s/\s+$//g; # Remove trailing spaces.
$url =~ s/\s+/\-/g; # Change one or more spaces to single hyphen.
$url =~ s/[^\w\-]//g; # Remove any non-word characters.
print "$title\n$url\n";
방금 빠른 테스트를했는데 효과가있는 것 같습니다. 바라건대 이것은 루비로 번역하기가 비교적 쉽습니다.
dbo.UrlEncode 에서 채택 된 T-SQL 구현 :
CREATE FUNCTION dbo.Slug(@string varchar(1024))
RETURNS varchar(3072)
AS
BEGIN
DECLARE @count int, @c char(1), @i int, @slug varchar(3072)
SET @string = replace(lower(ltrim(rtrim(@string))),' ','-')
SET @count = Len(@string)
SET @i = 1
SET @slug = ''
WHILE (@i <= @count)
BEGIN
SET @c = substring(@string, @i, 1)
IF @c LIKE '[a-z0-9--]'
SET @slug = @slug + @c
SET @i = @i +1
END
RETURN @slug
END
모델 클래스에 title 속성이 있다고 가정하면 다음과 같이 모델 내에서 to_param 메소드를 대체 할 수 있습니다.
def to_param
title.downcase.gsub(/ /, '-')
end
이 Railscast 에피소드 에는 자세한 내용이 있습니다. 다음을 사용하여 제목에 유효한 문자 만 포함되도록 할 수도 있습니다.
validates_format_of :title, :with => /^[a-z0-9-]+$/,
:message => 'can only contain letters, numbers and hyphens'
나는 그것이 매우 오래된 질문이라는 것을 알고 있지만 대부분의 브라우저는 이제 유니 코드 URL을 지원 하므로 문자를 제외한 모든 것을 (모든 언어에서 '-'로) 변환하는 XRegex 에서 훌륭한 솔루션을 찾았습니다 .
여러 프로그래밍 언어로 수행 할 수 있습니다.
패턴은 \\p{^L}+
이제 문자가 아닌 모든 문자를 '-'로 바꾸는 데 사용해야합니다.
xregex 모듈이 있는 node.js의 작업 예제
var text = 'This ! can @ have # several $ letters % from different languages such as עברית or Español';
var slugRegEx = XRegExp('((?!\\d)\\p{^L})+', 'g');
var slug = XRegExp.replace(text, slugRegEx, '-').toLowerCase();
console.log(slug) ==> "this-can-have-several-letters-from-different-languages-such-as-עברית-or-español"
루비에서 브라이언의 코드 :
title.downcase.strip.gsub(/\ /, '-').gsub(/[^\w\-]/, '')
downcase
, 소문자로 문자열을 전환 strip
선행 및 후행 공백, 첫 번째 제거 gsub
콜 g lobally 하위 대시 stitutes 공간을하고, 문자 나 대시없는 두 번째 제거합니다 모든 것을.
PermalinkFu 라는 작은 Ruby on Rails 플러그인 이 있습니다. 탈출 방법은 A에 대한 적합한 문자열로 변환을 수행 URL . 코드를 살펴보십시오. 그 방법은 매우 간단합니다.
ASCII가 아닌 문자 를 제거하려면 iconv lib를 사용하여 'utf-8'에서 'ascii // ignore // translit'으로 변환하십시오. 그런 다음 공백이 대시로 바뀌고 모든 것이 다운됩니다.
다음과 같은 헬퍼 방법을 사용할 수 있습니다. 유니 코드 문자를 변환 할 수 있습니다.
public static string ConvertTextToSlug(string s)
{
StringBuilder sb = new StringBuilder();
bool wasHyphen = true;
foreach (char c in s)
{
if (char.IsLetterOrDigit(c))
{
sb.Append(char.ToLower(c));
wasHyphen = false;
}
else
if (char.IsWhiteSpace(c) && !wasHyphen)
{
sb.Append('-');
wasHyphen = true;
}
}
// Avoid trailing hyphens
if (wasHyphen && sb.Length > 0)
sb.Length--;
return sb.ToString().Replace("--","-");
}
다음은 Jeff 코드의 (느리지 만 재미있게 작성하는) 버전입니다.
public static string URLFriendly(string title)
{
char? prevRead = null,
prevWritten = null;
var seq =
from c in title
let norm = RemapInternationalCharToAscii(char.ToLowerInvariant(c).ToString())[0]
let keep = char.IsLetterOrDigit(norm)
where prevRead.HasValue || keep
let replaced = keep ? norm
: prevWritten != '-' ? '-'
: (char?)null
where replaced != null
let s = replaced + (prevRead == null ? ""
: norm == '#' && "cf".Contains(prevRead.Value) ? "sharp"
: norm == '+' ? "plus"
: "")
let _ = prevRead = norm
from written in s
let __ = prevWritten = written
select written;
const int maxlen = 80;
return string.Concat(seq.Take(maxlen)).TrimEnd('-');
}
public static string RemapInternationalCharToAscii(string text)
{
var seq = text.Normalize(NormalizationForm.FormD)
.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark);
return string.Concat(seq).Normalize(NormalizationForm.FormC);
}
내 테스트 문자열 :
" I love C#, F#, C++, and... Crème brûlée!!! They see me codin'... they hatin'... tryin' to catch me codin' dirty... "
유래 솔루션은 매우 중요하지만, 현대적인 브라우저 (평소와 같이, IE 제외) 지금 잘 UTF8 인코딩을 처리 :
그래서 제안 된 솔루션을 업그레이드했습니다.
public static string ToFriendlyUrl(string title, bool useUTF8Encoding = false)
{
...
else if (c >= 128)
{
int prevlen = sb.Length;
if (useUTF8Encoding )
{
sb.Append(HttpUtility.UrlEncode(c.ToString(CultureInfo.InvariantCulture),Encoding.UTF8));
}
else
{
sb.Append(RemapInternationalCharToAscii(c));
}
...
}
편집 : 여기 에 RemapInternationalCharToAscii
메소드 코드 가 있습니다 (pastebin에는 없습니다).
정규 표현식 을 사용하지 않고이 작업을 수행하는 방식이 마음에 들었 으므로 PHP로 이식했습니다. 방금 is_between
문자를 확인 하는 함수를 추가했습니다 .
function is_between($val, $min, $max)
{
$val = (int) $val; $min = (int) $min; $max = (int) $max;
return ($val >= $min && $val <= $max);
}
function international_char_to_ascii($char)
{
if (mb_strpos('àåáâäãåa', $char) !== false)
{
return 'a';
}
if (mb_strpos('èéêëe', $char) !== false)
{
return 'e';
}
if (mb_strpos('ìíîïi', $char) !== false)
{
return 'i';
}
if (mb_strpos('òóôõö', $char) !== false)
{
return 'o';
}
if (mb_strpos('ùúûüuu', $char) !== false)
{
return 'u';
}
if (mb_strpos('çccc', $char) !== false)
{
return 'c';
}
if (mb_strpos('zzž', $char) !== false)
{
return 'z';
}
if (mb_strpos('ssšs', $char) !== false)
{
return 's';
}
if (mb_strpos('ñn', $char) !== false)
{
return 'n';
}
if (mb_strpos('ýÿ', $char) !== false)
{
return 'y';
}
if (mb_strpos('gg', $char) !== false)
{
return 'g';
}
if (mb_strpos('r', $char) !== false)
{
return 'r';
}
if (mb_strpos('l', $char) !== false)
{
return 'l';
}
if (mb_strpos('d', $char) !== false)
{
return 'd';
}
if (mb_strpos('ß', $char) !== false)
{
return 'ss';
}
if (mb_strpos('Þ', $char) !== false)
{
return 'th';
}
if (mb_strpos('h', $char) !== false)
{
return 'h';
}
if (mb_strpos('j', $char) !== false)
{
return 'j';
}
return '';
}
function url_friendly_title($url_title)
{
if (empty($url_title))
{
return '';
}
$url_title = mb_strtolower($url_title);
$url_title_max_length = 80;
$url_title_length = mb_strlen($url_title);
$url_title_friendly = '';
$url_title_dash_added = false;
$url_title_char = '';
for ($i = 0; $i < $url_title_length; $i++)
{
$url_title_char = mb_substr($url_title, $i, 1);
if (strlen($url_title_char) == 2)
{
$url_title_ascii = ord($url_title_char[0]) * 256 + ord($url_title_char[1]) . "\r\n";
}
else
{
$url_title_ascii = ord($url_title_char);
}
if (is_between($url_title_ascii, 97, 122) || is_between($url_title_ascii, 48, 57))
{
$url_title_friendly .= $url_title_char;
$url_title_dash_added = false;
}
elseif(is_between($url_title_ascii, 65, 90))
{
$url_title_friendly .= chr(($url_title_ascii | 32));
$url_title_dash_added = false;
}
elseif($url_title_ascii == 32 || $url_title_ascii == 44 || $url_title_ascii == 46 || $url_title_ascii == 47 || $url_title_ascii == 92 || $url_title_ascii == 45 || $url_title_ascii == 47 || $url_title_ascii == 95 || $url_title_ascii == 61)
{
if (!$url_title_dash_added && mb_strlen($url_title_friendly) > 0)
{
$url_title_friendly .= chr(45);
$url_title_dash_added = true;
}
}
else if ($url_title_ascii >= 128)
{
$url_title_previous_length = mb_strlen($url_title_friendly);
$url_title_friendly .= international_char_to_ascii($url_title_char);
if ($url_title_previous_length != mb_strlen($url_title_friendly))
{
$url_title_dash_added = false;
}
}
if ($i == $url_title_max_length)
{
break;
}
}
if ($url_title_dash_added)
{
return mb_substr($url_title_friendly, 0, -1);
}
else
{
return $url_title_friendly;
}
}
이제 모든 브라우저는 utf8 인코딩을 잘 처리하므로 @giamin에서 사용하는 HttpUtility.UrlEncode 와 같은 WebUtility.UrlEncode Method를 사용할 수 있지만 웹 응용 프로그램 외부에서 작동합니다.
아니, 아니. 당신은 모두 너무 잘못입니다. 분음 부호를 제외하고는 아시아의 캐릭터에 대한 것이지만 루비 개발자에게는 니혼 진 형제를 고려하지 않은 것이 수치입니다 .
Firefox와 Safari는 모두 비 ASCII 문자를 URL 에 표시하며 솔직히 멋지게 보입니다. ' http://somewhere.com/news/read/ お 前 た ち は ア ホ じ ゃ な い か い ' 와 같은 링크를 지원하는 것이 좋습니다 .
여기에 PHP 코드가 있지만, 방금 작성했지만 스트레스 테스트를하지 않았습니다.
<?php
function slug($str)
{
$args = func_get_args();
array_filter($args); //remove blanks
$slug = mb_strtolower(implode('-', $args));
$real_slug = '';
$hyphen = '';
foreach(SU::mb_str_split($slug) as $c)
{
if (strlen($c) > 1 && mb_strlen($c)===1)
{
$real_slug .= $hyphen . $c;
$hyphen = '';
}
else
{
switch($c)
{
case '&':
$hyphen = $real_slug ? '-and-' : '';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
$real_slug .= $hyphen . $c;
$hyphen = '';
break;
default:
$hyphen = $hyphen ? $hyphen : ($real_slug ? '-' : '');
}
}
}
return $real_slug;
}
예:
$str = "~!@#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04 コリン ~!@#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04 トーマス ~!@#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04 アーノルド ~!@#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04";
echo slug($str);
출력 : 코린과 토마스와 아놀드
'-and-'는 &가 '-and-'로 변경 되었기 때문입니다.
코드를 TypeScript로 이식했습니다. JavaScript에 쉽게 적용 할 수 있습니다.
최신 브라우저 나 ES6을 대상으로하는 경우 프로토 타입에 .contains
방법을 추가하고 대신 String
사용할 수 있습니다 .includes
.
if (!String.prototype.contains) {
String.prototype.contains = function (check) {
return this.indexOf(check, 0) !== -1;
};
}
declare interface String {
contains(check: string): boolean;
}
export function MakeUrlFriendly(title: string) {
if (title == null || title == '')
return '';
const maxlen = 80;
let len = title.length;
let prevdash = false;
let result = '';
let c: string;
let cc: number;
let remapInternationalCharToAscii = function (c: string) {
let s = c.toLowerCase();
if ("àåáâäãåą".contains(s)) {
return "a";
}
else if ("èéêëę".contains(s)) {
return "e";
}
else if ("ìíîïı".contains(s)) {
return "i";
}
else if ("òóôõöøőð".contains(s)) {
return "o";
}
else if ("ùúûüŭů".contains(s)) {
return "u";
}
else if ("çćčĉ".contains(s)) {
return "c";
}
else if ("żźž".contains(s)) {
return "z";
}
else if ("śşšŝ".contains(s)) {
return "s";
}
else if ("ñń".contains(s)) {
return "n";
}
else if ("ýÿ".contains(s)) {
return "y";
}
else if ("ğĝ".contains(s)) {
return "g";
}
else if (c == 'ř') {
return "r";
}
else if (c == 'ł') {
return "l";
}
else if (c == 'đ') {
return "d";
}
else if (c == 'ß') {
return "ss";
}
else if (c == 'Þ') {
return "th";
}
else if (c == 'ĥ') {
return "h";
}
else if (c == 'ĵ') {
return "j";
}
else {
return "";
}
};
for (let i = 0; i < len; i++) {
c = title[i];
cc = c.charCodeAt(0);
if ((cc >= 97 /* a */ && cc <= 122 /* z */) || (cc >= 48 /* 0 */ && cc <= 57 /* 9 */)) {
result += c;
prevdash = false;
}
else if ((cc >= 65 && cc <= 90 /* A - Z */)) {
result += c.toLowerCase();
prevdash = false;
}
else if (c == ' ' || c == ',' || c == '.' || c == '/' || c == '\\' || c == '-' || c == '_' || c == '=') {
if (!prevdash && result.length > 0) {
result += '-';
prevdash = true;
}
}
else if (cc >= 128) {
let prevlen = result.length;
result += remapInternationalCharToAscii(c);
if (prevlen != result.length) prevdash = false;
}
if (i == maxlen) break;
}
if (prevdash)
return result.substring(0, result.length - 1);
else
return result;
}
참고 URL : https://stackoverflow.com/questions/25259/how-does-stack-overflow-generate-its-seo-friendly-urls
'IT story' 카테고리의 다른 글
코드에서 안드로이드 세트 스타일 (0) | 2020.04.09 |
---|---|
다중 GitHub 계정 및 SSH 구성 (0) | 2020.04.09 |
Bash에서 -z는 무엇을 의미합니까? (0) | 2020.04.08 |
파이썬에서 "올림"키워드를 사용하는 방법 (0) | 2020.04.08 |
자바 스크립트 : Object Rename Key (0) | 2020.04.08 |