How does Stack Overflow generate its SEO-friendly URLs?

后端 未结 21 1847
-上瘾入骨i
-上瘾入骨i 2020-11-22 04:27

What is a good complete regular expression or some other process that would take the title:

How do you change a title to be part of the URL like Stack

21条回答
  •  抹茶落季
    2020-11-22 04:58

    I ported the code to TypeScript. It can easily be adapted to JavaScript.

    I am adding a .contains method to the String prototype, if you're targeting the latest browsers or ES6 you can use .includes instead.

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

提交回复
热议问题