In che modo Stack Overflow genera i suoi URL SEO-friendly?

Che cosa è una buona espressione regolare completa o qualche altro processo che prenderebbe il titolo:

Come si modifica un titolo per far parte dell’URL come Stack Overflow?

e trasformalo in

how-do-you-change-a-title-to-be-part-of-the-url-like-stack-overflow 

che viene utilizzato negli URL SEO-friendly su Stack Overflow?

L’ambiente di sviluppo che sto usando è Ruby on Rails , ma se ci sono altre soluzioni specifiche per la piattaforma (.NET, PHP, Django ), mi piacerebbe vederle anche io.

    Sono sicuro che io (o un altro lettore) incontrerò lo stesso problema su una piattaforma diversa su tutta la linea.

    Sto usando percorsi personalizzati e principalmente voglio sapere come modificare la stringa in modo da rimuovere tutti i caratteri speciali, è tutto in minuscolo e tutti gli spazi vengono sostituiti.

    Ecco come lo facciamo. Nota che ci sono probabilmente più condizioni di margine di quelle che ti rendi conto a prima vista.

    Questa è la seconda versione, srotolata per 5 volte più prestazioni (e sì, l’ho messa a confronto). Ho pensato di ottimizzarlo perché questa funzione può essere chiamata centinaia di volte per pagina.

     ///  /// Produces optional, URL-friendly version of a title, "like-this-one". /// hand-tuned for speed, reflects performance refactoring contributed /// by John Gietzen (user otac0n) ///  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(); } 

    Per vedere la versione precedente del codice che è stata sostituita (ma è funzionalmente equivalente a e 5 volte più veloce), visualizza la cronologia delle revisioni di questo post (fai clic sul link della data).

    Inoltre, il codice sorgente del metodo RemapInternationalCharToAscii può essere trovato qui .

    Ecco la mia versione del codice di Jeff. Ho apportato le seguenti modifiche:

    • I trattini sono stati aggiunti in modo tale da poter essere aggiunti, e quindi devono essere rimossi poiché si trattava dell’ultimo carattere nella stringa. Cioè, non vogliamo mai “my-slug-“. Ciò significa un’assegnazione di stringhe aggiuntiva per rimuoverla su questo caso limite. Ho lavorato a questo problema con l’iphening. Se confronti il ​​mio codice con Jeff, la logica per questo è facile da seguire.
    • Il suo approccio è basato esclusivamente sulla ricerca e ha perso molti caratteri che ho trovato negli esempi durante la ricerca su Stack Overflow. Per contrastare ciò, per prima cosa eseguo un passaggio di normalizzazione (le regole di confronto AKA menzionate nella domanda di overflow di Meta Stack caratteri non US-ASCII lasciati dall’URL completo (profilo) ) e quindi ignorano qualsiasi carattere al di fuori degli intervalli accettabili. Questo funziona la maggior parte del tempo …
    • … Per quando non funziona ho anche dovuto aggiungere una tabella di ricerca. Come accennato in precedenza, alcuni caratteri non si associano ad un basso valore ASCII quando normalizzati. Piuttosto che lasciarle, ho una lista di eccezioni manuale che è senza dubbio piena di buchi, ma è meglio di niente. Il codice di normalizzazione è stato ispirato dal grande post di Jon Hanna nella domanda Stack Overflow. Come posso rimuovere gli accenti su una stringa? .
    • La conversione del caso ora è anche facoltativa.

       public static class Slug { public static string Create(bool toLower, params string[] values) { return Create(toLower, String.Join("-", values)); } ///  /// 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 ///  ///  ///  ///  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; } } 

    Per ulteriori dettagli, i test unitari e una spiegazione del motivo per cui lo schema URL di Facebook è un po ‘più intelligente di Stack Overflow, ho una versione estesa di questo sul mio blog .

    Dovrai impostare un percorso personalizzato per indirizzare l’ URL al controller che lo gestirà. Dato che stai usando Ruby on Rails, ecco una introduzione all’uso del loro motore di routing.

    In Ruby, avrai bisogno di un’espressione regolare come sai già e qui c’è l’espressione regolare da usare:

     def permalink_for(str) str.gsub(/[^\w\/]|[!\(\)\.]+/, ' ').strip.downcase.gsub(/\ +/, '-') end 

    Puoi anche usare questa funzione JavaScript per generare in-form degli slug (questo è basato su / copiato da Django ):

     function makeSlug(urlString, filter) { // Changes, eg, "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 } 

    Per buona misura, ecco la funzione PHP in WordPress che lo fa … Penso che WordPress sia una delle piattaforms più popolari che utilizza collegamenti di fantasia.

         function sanitize_title_with_dashes ($ title) {
                 $ title = strip_tags ($ title);
                 // Mantieni gli ottetti sfuggiti.
                 $ title = preg_replace ('|% ([a-fA-F0-9] [a-fA-F0-9]) |', '--- $ 1 ---', $ title);
                 // Rimuovi i segni di percentuale che non fanno parte di un ottetto.
                 $ title = str_replace ('%', '', $ title);
                 // Ripristina gli ottetti.
                 $ title = preg_replace ('| --- ([a-fA-F0-9] [a-fA-F0-9]) --- |', '% $ 1', $ title);
                 $ title = remove_accents ($ title);
                 se (sembra_utf8 ($ title)) {
                         if (function_exists ('mb_strtolower'))) {
                                 $ title = mb_strtolower ($ title, 'UTF-8');
                         }
                         $ title = utf8_uri_encode ($ title, 200);
                 }
                 $ title = strtolower ($ title);
                 $ title = preg_replace ('/&.+?;/', '', $ title);  // uccide le  quadro
                 $ title = preg_replace ('/ [^% a-z0-9 _-] /', '', $ title);
                 $ title = preg_replace ('/ \ s + /', '-', $ title);
                 $ title = preg_replace ('| - + |', '-', $ title);
                 $ title = trim ($ title, '-');
                 return $ title;
         }
    

    Questa funzione e alcune delle funzioni di supporto sono disponibili in wp-includes / formatting.php.

    Se stai usando Edge Rails, puoi contare su Inflector.parametrize – ecco l’esempio della documentazione:

      class Person def to_param "#{id}-#{name.parameterize}" end end @person = Person.find(1) # => # <%= link_to(@person.name, person_path(@person)) %> # => Donald E. Knuth 

    Inoltre, se hai bisogno di gestire personaggi più esotici come gli accenti (éphémère) nella versione precedente di Rails, puoi usare una miscela di PermalinkFu e DiacriticsFu :

     DiacriticsFu::escape("éphémère") => "ephemere" DiacriticsFu::escape("räksmörgås") => "raksmorgas" 

    Non ho familiarità con Ruby on Rails, ma il seguente codice PHP (non verificato). Probabilmente puoi tradurre questo molto velocemente in Ruby on Rails se lo trovi utile.

     $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 

    Spero che aiuti.

    Non mi piace molto su Ruby o Rails, ma in Perl, questo è quello che farei:

     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"; 

    Ho appena fatto un test rapido e sembra funzionare. Speriamo che questo sia relativamente facile da tradurre in Ruby.

    Implementazione T-SQL, adattata da dbo.UrlEncode :

     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 

    Supponendo che la class del tuo modello abbia un attributo title, puoi semplicemente sovrascrivere il metodo to_param all’interno del modello, in questo modo:

     def to_param title.downcase.gsub(/ /, '-') end 

    Questo episodio di Railscast ha tutti i dettagli. Puoi anche assicurarti che il titolo contenga solo caratteri validi usando questo:

     validates_format_of :title, :with => /^[a-z0-9-]+$/, :message => 'can only contain letters, numbers and hyphens' 

    E i personaggi divertenti? Che cosa hai intenzione di fare per quelli? Le dieresi? Punteggiatura? Questi devono essere considerati. Fondamentalmente, userei un approccio white-list, al contrario degli approcci black list sopra: Descrivi quali caratteri permetteresti, quali caratteri convertirai (a cosa?) E poi cambierai il resto in qualcosa di significativo (“”) . Dubito che tu possa fare questo in una regex … Perché non basta scorrere i personaggi?

    So che è una domanda molto vecchia ma dal momento che la maggior parte dei browser ora supporta gli URL unicode ho trovato un’ottima soluzione in XRegex che converte tutto tranne le lettere (in tutte le lingue in “-“).

    Ciò può essere fatto in diversi linguaggi di programmazione.

    Il pattern è \\p{^L}+ e quindi devi solo usarlo per sostituire tutte le non lettere in ‘-‘.

    Esempio di lavoro in node.js con il modulo xregex .

     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" 

    Il codice di Brian, in Ruby:

     title.downcase.strip.gsub(/\ /, '-').gsub(/[^\w\-]/, '') 

    downcase trasforma la stringa in minuscolo, rimuove lo spazio gsub e finale, la prima chiamata gsub sottrae gli spazi con trattini e la seconda rimuove tutto ciò che non è una lettera o un trattino.

    C’è un piccolo plugin di Ruby on Rails chiamato PermalinkFu , che fa questo. Il metodo di escape fa la trasformazione in una stringa che è adatta per un URL . Dai un’occhiata al codice; quel metodo è abbastanza semplice.

    Per rimuovere caratteri non ASCII usa la lib iconv per tradurre in ‘ascii // ignore // translit’ da ‘utf-8’. Gli spazi vengono poi trasformati in trattini, tutto viene ridimensionato, ecc.

    È ansible utilizzare il seguente metodo di supporto. Può convertire i caratteri Unicode.

     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("--","-"); } 

    Ecco la mia versione (più lenta, ma divertente da scrivere) del codice di 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); } 

    La mia stringa di prova:

    " I love C#, F#, C++, and... Crème brûlée!!! They see me codin'... they hatin'... tryin' to catch me codin' dirty... "

    La soluzione StackOverflow è ottima, ma il browser moderno (ad eccezione di IE, come al solito) ora gestisce la codifica utf8:

    inserisci la descrizione dell'immagine qui

    Così ho aggiornato la soluzione proposta:

     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)); } ... } 

    Codice completo su Pastebin

    Modifica: ecco il codice per il metodo RemapInternationalCharToAscii (che manca nel pastebin).

    Mi è piaciuto il modo in cui è stato fatto senza utilizzare le espressioni regolari , quindi l’ho portato su PHP. Ho appena aggiunto una funzione chiamata is_between per controllare i caratteri:

     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; } } 

    Ora tutto il browser gestisce bene la codifica utf8, quindi puoi usare il metodo WebUtility.UrlEncode , che è come HttpUtility.UrlEncode usato da @giamin ma funziona al di fuori di un’applicazione web.

    Ho portato il codice a TypeScript. Può essere facilmente adattato a JavaScript.

    Sto aggiungendo un metodo .contains al prototipo String , se hai come target gli ultimi browser o ES6 puoi usare .includes invece.

     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; } 

    No, no, no. Hai talmente torto. Tranne il materiale diacritics-fu, ci stai arrivando, ma che dire dei personaggi asiatici (vergogna per gli sviluppatori di Ruby per non aver considerato i loro fratelli nihonjin ).

    Firefox e Safari mostrano entrambi caratteri non ASCII nell’URL , e francamente sono fantastici. È bello supportare collegamenti come ‘ http://somewhere.com/news/read/ お 前 た ち は ア ホ じ ゃ な い ..’.

    Quindi ecco un codice PHP che lo farà, ma l’ho appena scritto e non ho provato lo stress.

      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; } 

    Esempio:

     $str = "[email protected]#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04 コリン [email protected]#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04 トーマス [email protected]#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04 アーノルド [email protected]#$%^&*()_+-=[]\{}|;':\",./<>?\n\r\t\x07\x00\x04"; echo slug($str); 

    Uscite: コ リ ン -e- ト ー マ ス -e- ア ー ノ ル ド

    Il ‘-e-‘ è perché & è cambiato in ‘-e-‘.