Permalink. Need advice to improve code. Thank you,

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hello,
I created a String extension ( maybe shouldnt be an extension? ) to generate slugs for permakinks.
There are 4 options: intelligent, lowercase, maximumLength and minimumWordLength.

1 - A few working examples:
"A simple example".Slug() >> a-simple-example
"The problem #1 was solved".Slug() >> the-problem-number-1-was-solved
"Tom & Jerry?".Slug() >> tom-and-jerry
"I found the pen @Home...".Slug() >> i-found-the-pen-at-home
"They had 20% of proffit".Slug() >> they-had-20-percent-of-proffit
"She is a * for sure ...".Slug() >> she-is-a-start-for-sure
"She is sure 1+2=3!".Slug() >> she-is-sure-1-plus-2-equals-3
"It is nicer in Yellow/Orange".Slug() >> it-is-nicer-in-yellow-slash-orange
"Some words in PortuguÃs, EspaÃol and FranÃais".Slug() >>
some-words-in-portugues-espanol-and-francais
"The book is $40 and the pen is â20".Slug() >>
the-book-is-40-dollars-and-the-pen-is-20-euros
"The book is $20.18 and the pen is â12.10".Slug() >>
the-book-is-20-dollars-and-18-cents-and-the-pen-is-12-euros-and-10-cents
"The book is 40 and the pen is 20".Slug() >>
the-book-is-40-pounds-and-the-pen-is-20-yens
"The book is 20.18 and the pen is 12.10".Slug() >>
the-book-is-20-pounds-and-18-cents-and-the-pen-is-12-yens-and-10-cents
"The price is â1.0 or $1.35 or 0.85 or 105 ...".Slug() >>
the-price-is-1-euro-or-1-dollar-and-35-cents-or-0-pounds-and-85-cents-or-105-yens
"The price is 1.0â or 1.35$ or 0.85 or 105 ...".Slug() >>
the-price-is-1-euro-or-1-dollar-and-35-cents-or-0-pounds-and-85-cents-or-105-yens

2 - Not working examples
(A) "Say こんにちは in japanese".Slug();
Could the Japanese characters being "translated" to some king of representation of those characters?
(B) Strings with emails ... I am not sure how to deal with them.
For email maybe something like "name@domain.co.uk" would become "name-at-domain-dot-co-dot-uk"
(C) Strings with URLs. Again I am just not sure.
(D) The maximumLength is not working properly.
The problem is that the last word gets broken when the string is trimmed.
(E) Localization. Any suggestions?
I am not sure if I should add an argument (culture) and deal with the localization inside the code ...
... Or let people pass that is needed.

Any suggestion to solve problems in (2), improve the code or add new functionality are welcome!
The code is the following:

<div style="color:black; background-color:white
<pre><span style="color:blue public <span style="color:blue static <span style="color:blue class StringExtensions {

<span style="color:blue public <span style="color:blue static String Slug(<span style="color:blue this String value) {
<span style="color:blue return value.Slug(<span style="color:blue true, <span style="color:blue true, 120, 0);
}

<span style="color:blue public <span style="color:blue static String Slug(<span style="color:blue this String value, Boolean intelligent, Boolean lowercase, Int32 maximumLength, Int32 minimumWordLength) {

<span style="color:blue if (intelligent) {

<span style="color:green // Money >> THANK YOU LOUIS.FR for the Money code
value = Regex.Replace(value,
<span style="color:#a31515 @"((?<cur>[$â ])s*)?((?<int>[0-9]{1,3}(,[0-9]{3})*)(.(?<dec>[0-9]{1,2}))?|(?<int>[0-9]{1,3}(.[0-9]{3})*)(,(?<dec>[0-9]{1,2}))?|(?<int>[0-9]{4,}([.,](?<dec>[0-9]{1,2}))?))(?(cur)|s*(?<cur>[$â ]))",
(m) => {
<span style="color:blue string i = m.Groups[<span style="color:#a31515 "int"].Value.Replace(<span style="color:#a31515 ",", <span style="color:#a31515 "").Replace(<span style="color:#a31515 ".", <span style="color:#a31515 "");
<span style="color:blue int intValue = <span style="color:blue int.Parse(i);
<span style="color:green //String cur = m.Groups["cur"].Value.Replace("$", "dollar").Replace("â", "euro").Replace(" ", "pound").Replace(" ", "yen");

String cur = <span style="color:blue null;
<span style="color:blue switch (m.Groups[<span style="color:#a31515 "cur"].Value) {
<span style="color:blue case <span style="color:#a31515 "$":
cur = <span style="color:#a31515 "dollar";
<span style="color:blue break;
<span style="color:blue case <span style="color:#a31515 "â":
cur = <span style="color:#a31515 "euro";
<span style="color:blue break;
<span style="color:blue case <span style="color:#a31515 " ":
cur = <span style="color:#a31515 "pound";
<span style="color:blue break;
<span style="color:blue case <span style="color:#a31515 " ":
cur = <span style="color:#a31515 "yen";
<span style="color:blue break;
}
<span style="color:blue if (intValue != 1) cur += <span style="color:#a31515 "s";
<span style="color:blue string dec = m.Groups[<span style="color:#a31515 "dec"].Value;
<span style="color:blue if (!<span style="color:blue string.IsNullOrEmpty(dec)) {
<span style="color:blue int decValue = <span style="color:blue int.Parse(dec);
<span style="color:blue if (decValue == 0)
dec = <span style="color:#a31515 "";
<span style="color:blue else
dec = <span style="color:#a31515 " and " + decValue + (decValue > 1 ? <span style="color:#a31515 " cents" : <span style="color:#a31515 " cent");
}
<span style="color:blue return intValue + <span style="color:#a31515 " " + cur + dec;
});

<span style="color:green // Rules
IList rules = <span style="color:blue new[] {
<span style="color:blue new { In = <span style="color:#a31515 @"s*&s*", Out = <span style="color:#a31515 @" and " },
<span style="color:blue new { In = <span style="color:#a31515 @"s*#", Out = <span style="color:#a31515 @" number " },
<span style="color:blue new { In = <span style="color:#a31515 @"s*@s*", Out = <span style="color:#a31515 @" at " },
<span style="color:blue new { In = <span style="color:#a31515 @"s*%s*", Out = <span style="color:#a31515 @" percent " },
<span style="color:blue new { In = <span style="color:#a31515 @"s**s*", Out = <span style="color:#a31515 @" start " },
<span style="color:blue new { In = <span style="color:#a31515 @"(s*=s*)", Out = <span style="color:#a31515 @" equals " },
<span style="color:blue new { In = <span style="color:#a31515 @"s*+s*", Out = <span style="color:#a31515 @" plus " },
<span style="color:blue new { In = <span style="color:#a31515 @"s*(\|/)s*", Out = <span style="color:#a31515 @" slash " }
}.ForEach(r => value = Regex.Replace(value, r.In, r.Out)).ToList();

}

String slug = value.RemoveDiacritics();

<span style="color:blue if (lowercase)
slug = slug.ToLower();

slug = Regex.Replace(slug, <span style="color:#a31515 @"[^a-z0-9s-]", <span style="color:#a31515 "");

slug = Regex.Replace(slug, <span style="color:#a31515 @"s+", <span style="color:#a31515 " ").Trim();

slug = String.Join(<span style="color:#a31515 "-", slug.Split(<span style="color:#a31515 ).Where(x => x.Length >= minimumWordLength));

slug = slug.Substring(0, slug.Length <= maximumLength ? slug.Length : maximumLength).Trim();

<span style="color:blue return slug;

} <span style="color:green // Slug

<span style="color:green // RemoveDiacritics
<span style="color:blue public <span style="color:blue static String RemoveDiacritics(<span style="color:blue this String value) {

<span style="color:green // Define normalized
String normalized = value.Normalize(NormalizationForm.FormD);
StringBuilder builder = <span style="color:blue new StringBuilder();

<span style="color:green // Strip diacritics
<span style="color:blue for (Int32 i = 0; i < normalized.Length; i++) {
UnicodeCategory unicode = CharUnicodeInfo.GetUnicodeCategory(normalized);
<span style="color:blue if (unicode != UnicodeCategory.NonSpacingMark) {
builder.Append(normalized);
}
}

<span style="color:green // Return stripped
<span style="color:blue return (builder.ToString().Normalize(NormalizationForm.FormC));

} <span style="color:green // RemoveDiacritics
[/code]

<br/>
Thank You,
Miguel


<br/>

View the full article
 


Write your reply...
Back
Top