স্ট্যাক ওভারফ্লো কীভাবে এর এসইও-বান্ধব ইউআরএল উত্পন্ন করে?


253

একটি ভাল সম্পূর্ণ নিয়মিত প্রকাশ বা শিরোনাম গ্রহণ করবে এমন অন্য কোনও প্রক্রিয়া কী:

স্ট্যাক ওভারফ্লো এর মতো URL এর অংশ হতে আপনি কীভাবে কোনও শিরোনাম পরিবর্তন করবেন?

এবং এটি চালু

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

যা স্ট্যাক ওভারফ্লোতে এসইও-বান্ধব URL গুলিতে ব্যবহৃত হয়?

আমি যে বিকাশের পরিবেশটি ব্যবহার করছি তা হ'ল রুবি অন রেলে , তবে যদি প্ল্যাটফর্ম-নির্দিষ্ট কিছু সমাধান (। নেট, পিএইচপি, জাজানো ) থাকে তবে আমি সেগুলি দেখতেও পছন্দ করব।

আমি নিশ্চিত যে আমি (বা অন্য পাঠক) একই সমস্যাটি লাইনের নীচে ভিন্ন প্ল্যাটফর্মে উপস্থিত করব।

আমি কাস্টম রুটগুলি ব্যবহার করছি এবং আমি প্রধানত সমস্ত বিশেষ অক্ষরগুলিতে স্ট্রিং কীভাবে পরিবর্তন করতে হবে তা জানতে চাই, এটি সমস্ত ছোট হাতের অক্ষর এবং সমস্ত সাদা স্থান প্রতিস্থাপন করা হয়েছে।


মজার চরিত্রগুলি সম্পর্কে কী? আপনি তাদের সম্পর্কে কি করতে যাচ্ছেন? Umlauts? বিরাম চিহ্ন? এগুলি বিবেচনা করা দরকার। মূলত, আমি উপরের কালো-তালিকা পদ্ধতির বিপরীতে একটি সাদা-তালিকা পদ্ধতির ব্যবহার করব: আপনি কোন অক্ষরকে অনুমতি দেবেন, কোন অক্ষরগুলিকে আপনি (কোনটি?) রূপান্তর করবেন এবং তারপরে বাকীটি অর্থপূর্ণ ("") রূপান্তর করবেন তা বর্ণনা করুন । আমি সন্দেহ করি আপনি এটি একটি রেজেক্সে করতে পারেন ... কেন কেবল চরিত্রগুলি লুপ করবেন না?
ড্যারেন টমাস

1
মেটাতে স্থানান্তরিত করা উচিত ; প্রশ্ন এবং উত্তর উভয়ই বিশেষত এসও বাস্তবায়নের সাথে মোকাবিলা করে এবং স্বীকৃত উত্তরটি @ জেফএটউড থেকে প্রাপ্ত।
ক্যাস্পারনি

19
@ ক্যাস্পারওন আপনার কি মনে হয় জেফকে কিছু অ-মেটা খ্যাতির অনুমতি দেওয়া হয়নি? প্রশ্নটি "কীভাবে কেউ এই জাতীয় কিছু করতে পারে" সম্পর্কে, বিশেষত "এখানে কীভাবে এটি করা হয়" তা নয়।
পাওলো ইবারম্যান

@ পাওলোবারম্যান: জেফ কিছুটা নন-মেটা খ্যাতি অর্জনের বিষয়ে নয় (তাঁর কতটা খ্যাতি সত্যই আমার উদ্বেগ নয়); প্রশ্ন সংস্থা বিশেষত স্ট্যাকওভারফ্লো এর বাস্তবায়নের উল্লেখ করেছে সুতরাং এটি মেটাতে থাকার জন্য যুক্তিযুক্ত।
ক্যাস্পারনি

উত্তর:


300

আমরা এটি কীভাবে করব তা এখানে। মনে রাখবেন যে সম্ভবত আপনি প্রথম নজরে উপলব্ধি করার চেয়ে আরও বেশি প্রান্তের শর্ত রয়েছে।

এটি দ্বিতীয় সংস্করণ, 5x আরও পারফরম্যান্সের জন্য তালিকাভুক্ত নয় (এবং হ্যাঁ, আমি এটি বেঞ্চমার্ক করেছি)। আমি অনুভব করেছি যে আমি এটি সর্বোত্তম করব কারণ এই ফাংশনটি প্রতি পৃষ্ঠায় কয়েকবার বলা যেতে পারে।

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

কোডটির পূর্ববর্তী সংস্করণটি এটি প্রতিস্থাপিত হয়েছে (তবে কার্যকরীভাবে সমান এবং 5x দ্রুত) এটি দেখতে এই পোস্টের পুনর্বিবেচনার ইতিহাসটি দেখুন (তারিখের লিঙ্কটিতে ক্লিক করুন)।

এছাড়াও, RemapInternationalCharToAsciiপদ্ধতি উত্স কোড এখানে পাওয়া যাবে


24
এটি এমন এক সংস্করণ সহ চমৎকার হবে যা কেবল উচ্চারণযুক্ত অক্ষরগুলিকে না ফেলে åäö বরং পরিবর্তে এওকে তাদের deaccentuate ... ^^
ওসকার ডুভের্ন

22
@ ফস্করটির স্টাবটি এখানে RemapInternationalCharToAscii()রয়েছে মেটা.স্ট্যাকেক্সেঞ্জার.কম
জেফ

3
এটা অসাধারণ. আমি এখন পর্যন্ত কেবলমাত্র একমাত্র পরিবর্তনটি হ'ল "যদি (i == ম্যাক্সেলন) বিরতি;" হতে "যদি (sb.Length == ম্যাক্সেলেন) বিরতি;" আমি যে স্ট্রিংটিতে যাচ্ছি তার মধ্যে কেবলমাত্র প্রচুর অবৈধ চরিত্র রয়েছে
টম চ্যান্টলার

4
একটি সামান্য অপ্টিমাইজেশন: if (prevdash) sb.Length -= 1; return sb.ToString();শেষ ifবিবৃতি পরিবর্তে ।
মার্ক হার্ট

8
@ ডমার sb.Length == maxlen break;বগি হয় যদি ম্যাক্সেলেন্থ -১-এ সাইন "ß" হয় তবে এটি "এসএস" এ রূপান্তরিত হয় sb.Length == maxleneকখনই সত্য হবে না, এটি পরীক্ষা করার চেয়ে ভাল (sb.Length > = maxlen)
হেনরিক স্টেনবেক

32

জেফের কোডটির আমার সংস্করণটি এখানে। আমি নিম্নলিখিত পরিবর্তনগুলি করেছি:

  • হাইফেনগুলি এমনভাবে যুক্ত করা হয়েছিল যাতে একটি যুক্ত করা যায় এবং তারপরে এটি সরানোর প্রয়োজন কারণ এটি স্ট্রিংয়ের শেষ চরিত্র ছিল। তা হচ্ছে, আমরা কখনই "মাই-স্লাগ-" চাই না। এর অর্থ এই প্রান্তের ক্ষেত্রে এটি সরাতে অতিরিক্ত স্ট্রিং বরাদ্দ। আমি বিলম্ব-হাইফেনিংয়ের মাধ্যমে এটিকে ঘিরে কাজ করেছি। যদি আপনি আমার কোডটিকে জেফের যুক্তির সাথে তুলনা করেন তবে এটি অনুসরণ করা সহজ।
  • স্ট্যাক ওভারফ্লো নিয়ে গবেষণার সময় তার পদ্ধতির বিশুদ্ধরূপে অনুসন্ধানের ভিত্তি রয়েছে এবং উদাহরণগুলিতে প্রচুর চরিত্রগুলি খুঁজে পেয়েছি missed এটির মোকাবিলা করার জন্য, আমি প্রথমে একটি নরমালাইজেশন পাস (মেটা স্ট্যাক ওভারফ্লো প্রশ্নে উল্লিখিত একেএ কোলিশেশনটি ইউএস-এএসসিআইআই অক্ষর পূর্ণ (প্রোফাইল) ইউআরএল থেকে বাদ পড়ে ) এবং তারপরে গ্রহণযোগ্য ব্যাপ্তির বাইরে থাকা কোনও অক্ষরকে উপেক্ষা করব। এটি বেশিরভাগ সময় কাজ করে ...
  • ... যখন এটি না হয় তখন আমারও একটি সন্ধানের টেবিল যুক্ত করতে হবে। উপরে উল্লিখিত হিসাবে, কিছু অক্ষর স্বাভাবিক হওয়ার সময় কম ASCII মান মানচিত্র করে না। এগুলি বাদ দেওয়ার পরিবর্তে আমি ব্যতিক্রমগুলির একটি ম্যানুয়াল তালিকা পেয়েছি যা নিঃসন্দেহে গর্তে পূর্ণ, তবে এটি কোনও কিছুর চেয়ে ভাল। নরমালাইজেশন কোডটি স্ট্যান্ড ওভারফ্লো প্রশ্নে জনা হানার দুর্দান্ত পোস্ট দ্বারা অনুপ্রাণিত হয়েছিল আমি কীভাবে স্ট্রিংয়ে অ্যাকসেন্টগুলি সরিয়ে ফেলতে পারি?
  • কেস রূপান্তর এখন alচ্ছিক।

    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
        /// /meta/7435/non-us-ascii-characters-dropped-from-full-profile-url/7696#7696
        /// /programming/25259/how-do-you-include-a-webpage-title-as-part-of-a-webpage-url/25486#25486
        /// /programming/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;
        }
    }

অধিক বিবরণের জন্য, ইউনিট পরীক্ষা এবং কেন একটি ব্যাখ্যা ফেসবুক এর URL টি প্রকল্প স্ট্যাক উপচে চেয়ে একটু স্মার্ট, আমি একটি পেয়েছেন এই প্রসারিত সংস্করণ আমার ব্লগে


4
+1 এটি দুর্দান্ত ড্যান। এর পরিবর্তে সম্ভবত পরিবর্তিত if (i == maxlen) break;হওয়া সম্পর্কে আমি আপনার ব্লগে একটি মন্তব্যও যুক্ত করেছি if (sb.Length == maxlen) break;যাতে আপনি যদি অনেকগুলি শ্বেতস্থান / অবৈধ অক্ষরের সাথে একটি স্ট্রিং দিয়ে যান তবে আপনি এখনও পছন্দসই দৈর্ঘ্যের একটি স্লাগ পেতে পারেন, তবে কোডটি এটির মতোই শেষ হতে পারে might এটি ব্যাপকভাবে ছাঁটাই (উদাহরণস্বরূপ আপনি যেখানে 80 টি স্পেস দিয়ে শুরু করবেন সেই ক্ষেত্রে বিবেচনা করুন ...)। এবং জেফের কোডের বিপরীতে 10,000,000 পুনরাবৃত্তির মোটামুটি বেঞ্চমার্ক এটিকে প্রায় একই গতি হিসাবে দেখিয়েছে।
টম চ্যান্টলার

1
ধন্যবাদ, আমার ব্লগে প্রতিক্রিয়া জানালেন এবং সেখানে এবং তারপরে তার কোড ঠিক করেছেন। কোডটি বেঞ্চমার্ক করার জন্যও ধন্যবাদ। আগ্রহীদের জন্য এটি জেফের সমতুল্য ছিল।
ড্যানএইচ

2
দেখে মনে হচ্ছে স্লাগের সাথে কিছু সমস্যা রয়েছে re ক্রিয়েট (): pp এর বড় আকারের সংস্করণগুলি সঠিকভাবে রূপান্তরিত হয় না ignored উপেক্ষা করা হয় while সাধারণত আপনি "å" কে "এএ", "ø" "ওয়ে" এবং "æ" "এএ" তে রূপান্তর করবেন। দ্বিতীয় (sb.Length == ম্যাক্সেলেন) বিরতি; ম্যাক্সএলঘাট -১ এ সাইনটি "ß" (এসবি। লেন্থ == ম্যাক্সেলেন) হলে সত্যই বোধগম্য নয় (sb.Length> = ম্যাক্সেলেন) এর জন্য পরীক্ষা করা ভাল। আমি চাপা পড়েছি যে আপনি যে কোনও এলোমেলো অবস্থান কাটেন এবং শেষ "-" কেটে না ফেলেছেন, এটি আপনাকে শেষ পর্যন্ত একটি অবাঞ্ছিত শব্দ দিয়ে শেষ করা থেকে বাঁচাবে: যেন শেষ "স" এর পরে আপনাকে "দৃ cut়তার সাথে" কাটাতে হবে "
হেনরিক স্টেনবেক

@ ড্যানএইচ কোডটির জাভাস্ক্রিপ্ট সংস্করণ থাকা ভাল হবে।
ফ্রেশব্লুড

16

আপনি নিয়ন্ত্রণের URL টি নির্দেশ করতে একটি কাস্টম রুট সেটআপ করতে চান যা এটি পরিচালনা করবে। আপনি যেহেতু রুবেল অন রেল ব্যবহার করছেন তাই এখানে একটি ভূমিকা রয়েছে ব্যবহার করছেন, তাই তাদের রাউটিং ইঞ্জিনটি ব্যবহার করার হয়েছে।

রুবিতে আপনার একটি নিয়মিত প্রকাশের প্রয়োজন হবে যেমনটি আপনি ইতিমধ্যে জানেন এবং ব্যবহারের জন্য এখানে নিয়মিত প্রকাশ রয়েছে:

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

11

আপনি এই জাভাস্ক্রিপ্ট ফাংশনটি স্লাগের ইন-ফর্ম জেনারেশনের জন্যও ব্যবহার করতে পারেন (এটি জাজানো থেকে অনুলিপি / অনুলিপিযুক্ত ):

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
}

কিছু লেট বা কনস্টের যোগ করা দুর্দান্ত হবে কারণ এটি ভ্যানিলা জেএস নয়।
আদিত্য আনন্দ

8

ভাল পরিমাপের জন্য, এখানে ওয়ার্ডপ্রেসে পিএইচপি ফাংশন এটি করে ... আমি মনে করি যে ওয়ার্ডপ্রেস অভিনব লিঙ্কগুলি ব্যবহার করে এমন একটি জনপ্রিয় প্ল্যাটফর্ম of

    ফাংশন স্যানিটাইজ_উইট_ড্যাশস ($ শিরোনাম) {
            $ শিরোনাম = স্ট্রিপ_ট্যাগ ($ শিরোনাম);
            // পালানো অক্টেট সংরক্ষণ করুন।
            $ শিরোনাম = পূর্ববর্তী স্থান ('|% ([a-fA-F0-9] [a-fA-F0-9])) |', '--- $ 1 ---', $ শিরোনাম);
            // এমন এক শতাংশ লক্ষণগুলি সরান যা কোনও অক্টের অংশ নয়।
            $ শিরোনাম = str_replace ('%', '', $ শিরোনাম);
            // অক্টেটগুলি পুনরুদ্ধার করুন।
            $ শিরোনাম = পূর্ববর্তী স্থান ('| --- ([a-fA-F0-9] [a-fA-F0-9]) --- |', '% $ 1', $ শিরোনাম);
            $ শিরোনাম = সরানো_অ্যাকসেন্টস ($ শিরোনাম);
            যদি (মনে হয়_টফ 8 ($ শিরোনাম)) {
                    যদি (ফাংশন_অস্তি ('এমবি_স্ট্রোলার')) {
                            $ শিরোনাম = এমবি_স্ট্রোলটার ($ শিরোনাম, 'ইউটিএফ -8');
                    }
                    $ শিরোনাম = utf8_uri_encode ($ শিরোনাম, 200);
            }
            $ শিরোনাম = স্ট্রোলটার ($ শিরোনাম);
            $ শিরোনাম = পূর্ববর্তী স্থান ('/ &.+?;/', '', $ শিরোনাম); // সত্তা হত্যা
            $ শিরোনাম = পূর্ববর্তী স্থান ('/ [^% a-z0-9 _-] /', '', $ শিরোনাম);
            $ শিরোনাম = পূর্ববর্তী স্থান ('/ \ s + /', '-', $ শিরোনাম);
            $ শিরোনাম = পূর্ববর্তী স্থান ('| - + |', '-', $ শিরোনাম);
            $ শিরোনাম = ছাঁটা ($ শিরোনাম, '-');
            প্রত্যাবর্তন $ শিরোনাম;
    }

এই ফাংশনটির পাশাপাশি কিছু সমর্থনকারী ফাংশন ডাব্লুপি-অন্তর্ভুক্ত / ফরম্যাটিং.এফপিতে পাওয়া যাবে।


6
এটি পুরো উত্তর নয়। আপনি মতো কাজগুলির উধাও: remove_accents, seems_utf8...
নিকোলা Loncar

সম্পূর্ণ করার জন্য @ কীভাবে git clone git://core.git.wordpress.org/wp-includes/formatting.php
গীকের

5

আপনি যদি রেল প্রান্ত ব্যবহার করে থাকেন তবে আপনি ইনফ্লেক্টর.প্রেমেট্রাইজ উপর নির্ভর করতে পারেন - ডকুমেন্টেশন থেকে উদাহরণ এখানে:

  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="https://stackoverflow.com/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"

5

আমি রিলে অন রুবেলের সাথে পরিচিত নই, তবে নিম্নলিখিতটি (অরীক্ষিত) পিএইচপি কোড রয়েছে। আপনি যদি এটি দরকারী মনে করেন তবে খুব সম্ভবত আপনি এটি খুব তাড়াতাড়ি রেল অন রুবেলে অনুবাদ করতে পারেন।

$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

আশা করি এটা কাজে লাগবে.


4

আমি রুবি বা রেলগুলি সম্পর্কে খুব বেশি কিছু করি না, তবে পার্লে, আমি যা করতাম তা এই:

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

আমি কেবল একটি দ্রুত পরীক্ষা করেছি এবং এটি কাজ করে বলে মনে হচ্ছে। আশা করি এটি রুবিতে অনুবাদ করা তুলনামূলক সহজ।


4

টি-এসকিউএল বাস্তবায়ন, dbo.UllEncode থেকে অভিযোজিত :

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

4

আমি জানি এটি খুব পুরানো প্রশ্ন তবে বেশিরভাগ ব্রাউজারগুলি এখন ইউনিকোড ইউআরএল সমর্থন করে আমি এক্সরেজেক্সে একটি দুর্দান্ত সমাধান পেয়েছি যা অক্ষর ব্যতীত সমস্ত কিছুকে রূপান্তর করে (সমস্ত ভাষায় '-' তে))

এটি বেশ কয়েকটি প্রোগ্রামিং ভাষায় করা যেতে পারে।

প্যাটার্নটি হ'ল \\p{^L}+এবং তারপরে আপনাকে '-' তে সমস্ত অ-অক্ষর প্রতিস্থাপন করতে এটি ব্যবহার করতে হবে।

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"

3

আপনার মডেল শ্রেণির একটি শিরোনাম বৈশিষ্ট্য রয়েছে তা ধরে নিয়ে, আপনি কেবলমাত্র মডেলের মধ্যে টো_প্যারাম পদ্ধতিটি ওভাররাইড করতে পারেন:

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

এই রেলকাস্ট পর্বে সমস্ত বিবরণ রয়েছে। আপনি নিশ্চিত করতে পারেন যে শিরোনামটিতে এটি ব্যবহার করে বৈধ অক্ষর রয়েছে:

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

2

ব্রায়ানের কোড, রুবিতে:

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

downcaseস্ট্রিংটিকে ছোট হাতের অক্ষরে পরিণত করে, stripশীর্ষস্থানীয় এবং অনুসরণকারী শ্বেতস্পেস সরিয়ে দেয়, প্রথম gsubকল জি ল্যাবালি সাব ড্যাশ সহ স্পেসগুলি স্থির করে এবং দ্বিতীয়টি অক্ষর বা ড্যাশ নয় এমন সমস্ত কিছু সরিয়ে দেয়।


2

সেখানে পাগল একটি ছোট রুবি নামক প্লাগইন PermalinkFu , যে এই আছে। পালাবার পদ্ধতি একটি স্ট্রিং একটি জন্য উপযুক্ত যে মধ্যে রূপান্তর করে URL টি । কোডটি একবার দেখুন; যে পদ্ধতিটি বেশ সহজ।

অ- এসসিআইআই অক্ষর অপসারণ করতে এটি 'ইউএসএফআই / উপেক্ষা // ট্রান্সলিট' থেকে 'ইউটিএফ -8' থেকে অনুবাদ করতে আইকনভ লাইব ব্যবহার করে। স্পেসগুলি তখন ড্যাশগুলিতে পরিণত হয়, সবকিছু হ্রাস করা হয় ইত্যাদি etc.


এটি পুরোপুরি কার্যকর হলেও, আমি একরকম মনে করি এটি খুব কার্যকর নয়।
নটহাগো

2

আপনি নিম্নলিখিত সহায়ক পদ্ধতি ব্যবহার করতে পারেন। এটি ইউনিকোড অক্ষরকে রূপান্তর করতে পারে।

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

2

জেফের কোডটির আমার (ধীর, তবে মজাদার লেখা) সংস্করণটি এখানে:

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


2

Stackoverflow সমাধান মহান, কিন্তু আধুনিক ব্রাউজারে (আইই বাদ যথারীতি) এখন চমত্কারভাবে 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 মধ্যে অনুপস্থিত)।


উইকিপিডিয়া অনুসারে , আইডিএনএ সমর্থনকারী প্রথম অ্যাপ্লিকেশনগুলির মধ্যে মোজিলা ১.৪, নেটস্কেপ .1.১, অপেরা .1.১১ ছিল। আইডিএন সমর্থন সরবরাহ করার জন্য একটি ব্রাউজার প্লাগইন ইন্টারনেট এক্সপ্লোরার 6 এর জন্য উপলব্ধ। ইন্টারনেট এক্সপ্লোরার .0.০ এবং উইন্ডোজ ভিস্তার ইউআরএল API গুলি আইডিএন এর জন্য স্থানীয় সমর্থন সরবরাহ করে। ইউটিএফ -8 টি অক্ষর অপসারণ করার মতো শব্দগুলি সময়ের অপচয়। দীর্ঘজীবী UTF-8 !!!
মুহাম্মদ রেহান সাইদ

1

আমি নিয়মিত এক্সপ্রেশন না ব্যবহার করে এটি করার পদ্ধতিটি পছন্দ করেছি , তাই আমি এটি পিএইচপি-তে পোর্ট করেছি। আমি কেবলমাত্র 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;
    }
}

1

এখন সমস্ত ব্রাউজার দুর্দান্তভাবে utf8 এনকোডিং হ্যান্ডেল করে, তাই আপনি ওয়েব ইউটিলিটি.উড়লিএনকোড পদ্ধতিটি ব্যবহার করতে পারেন এটি এর মতো HTTPUटिल.UrlEncode @GGININ দ্বারা ব্যবহৃত তবে এটি ওয়েব অ্যাপ্লিকেশনের বাইরে কাজ করে।


1

আমি কোডটি টাইপস্ক্রিপ্টে রেখেছি। এটি সহজেই জাভাস্ক্রিপ্টের সাথে মানিয়ে নেওয়া যায়।

আমি প্রোটোটাইপটিতে একটি .containsপদ্ধতি যুক্ত Stringকরছি, আপনি যদি সর্বশেষতম ব্রাউজারগুলি লক্ষ্য করে থাকেন বা ES6 আপনি .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;
        }

0

না না না. আপনি সব খুব ভুল। ডায়াক্রিটিক্স-ফু স্টাফ বাদে আপনি সেখানে যাচ্ছেন, তবে এশিয়ান চরিত্রগুলি সম্পর্কে (রুবি বিকাশকারীদের নিহোনজিন ভাইদের বিবেচনা না করার জন্য লজ্জা )।

ফায়ারফক্স এবং সাফারি উভয়ই ইউআরএল -এ ASCII অক্ষর প্রদর্শন করে এবং সত্যই তারা দুর্দান্ত দেখায়। ' Http://somewhere.com/news/read/ ' links 前 た ち ち は ア ホ じ ゃ な い か い 'এর মতো লিঙ্কগুলি সমর্থন করে ভাল লাগছে ।

সুতরাং এখানে কিছু পিএইচপি কোড রয়েছে যা এটি করবে, তবে আমি কেবল এটি লিখেছি এবং এটির পরীক্ষামূলক চাপ দিয়েছি না।

<?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);

আউটপুট: コ リ ン-এবং- ト ー マ ス-এবং- ス ー ノ ノ ル

'-আর-' কারণ & '' এবং '' তে পরিবর্তিত হয়েছে।


4
এই তথ্যের টুকরোগুলি সম্পর্কে কী বলব আমি সত্যিই জানি না।
sjas

3
এটি যখন স্যুইচ কেস স্টেটমেন্টটি ব্যবহার করবেন না তখন এটি একটি দুর্দান্ত উদাহরণ।
নিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.