PDA

View Full Version : Clean کردن یک متن برای استفاده در Url



hakan648
سه شنبه 30 آبان 1391, 00:32 صبح
سلام

دنبال یک روش برای پاکسازی متن برای استفاده در Url هستم. ( و نه Decode کردن! )
برای مثال سایتهای DotNetTips.info , StackOverFlow.com بخوبی از این سیستم استفاده می کنند.
در این سایت ها حروفی غیر از حروف اصلی حذف می شوند و بجای آنها "-" قرار می گیرد. ( البته با یک سری شرط و شروط دیگر که خارج از بحث هستند)

حالا یک نمونه خوب (http://stackoverflow.com/a/25486/1146395)از خود StackOverFlow پیدا کردم اما با حروف Unicode مشکل داره.

بعد از تست کردن کد فوق ، تصمیم گرفتم یک Regular Expression بنویسم که فقط حروف فارسی ، انگلیسی و عدد قبول کند:

[^a-zA-Z0-9\u0600-\u06FF]+

اما حروف عربی و علامت هم قبول می کند.

نتیجه ی replace کردن رشته ی "تبدیل صفحات یک فایل PDF به تصویر، با استفاده از Acrobat SDK" با Regular Expression فوق ، مقدار "تبدیل-صفحات-یک-فایل-PDF-به-تصویر،-با-استفاده-از-Acrobat-SDK" می باشد.

که حرف "،" هم باید جایگزین شود که نشده است.

راهی که میدونم اینه که در این Range ، مقدایر عربی و علامت رو حذف کنم اما دقیقا نمیدونم چه حروف و علامت هایی رو باید حذف کنم.
اگر به این جدول (http://www.ssec.wisc.edu/~tomw/java/unicode.html) هم توجه کنید ، میبینید که تعداد این حروف بسیار زیاد بوده و امکان تمایز بین حروف و خارج کردن آنها از بازه ی فوق ، براحتی امکان پذیر نیست.

پست های جناب موسوی رو هم در این تاپیک ها ( -1- (http://barnamenevis.org/showthread.php?292675) ، -2- (http://barnamenevis.org/showthread.php?292675) ) مطالعه کردم ولی خروجی همچنان مشابه فوق است.

در نهایت فکر می کنم که مسئله ( Clean کردن متن و استفاده در Url ) رو باید با Regex حل کنم ، اما بیشتر خرسند میشم اگه راه حل های مختلف ( و البته کارا ! ) رو هم از شما دوستان یاد بگیرم.

( برای تست راه حل ها هم میتونید عبارت هایی که شامل علامت، حروف عربی، ... هستند در این صفحه (http://www.dotnettips.info/View/Mosaic)رو با راه حلتون تست کنید و با نتیجه ی Clean شده مقایسه کنید )

با تشکر از همه ی دوستان عزیز!

hakan648
چهارشنبه 01 آذر 1391, 14:07 عصر
در حین تست هایی که می کردم بعضی از کرکترهارو با متدهای کلاس char تست کردم و متوجه شدم که گروه کرکتر "،" با گروه کرکترهای فارسی ( و عربی ) دیگه فرق داره :

char.GetUnicodeCategory('');
Empty character literal
char.GetUnicodeCategory('T');
UppercaseLetter
char.GetUnicodeCategory('t');
LowercaseLetter
char.GetUnicodeCategory('0');
DecimalDigitNumber
char.GetUnicodeCategory('.');
OtherPunctuation
char.GetUnicodeCategory('ر');
OtherLetter
char.GetUnicodeCategory('ء');
OtherLetter
char.GetUnicodeCategory('ئ');
OtherLetter
char.GetUnicodeCategory('،');
OtherPunctuation

در نتیجه گروه OtherLetter رو هم به عنوان کرکترهای مجاز معرفی کردم و با تست هایی که انجام دادم ، نتیجه ای برابر با اینجا (http://www.dotnettips.info/View/Mosaic) گرفتم.

در نهایت همون کدی که از StackOverFlow (http://stackoverflow.com/a/25486/1146395) پیدا کرده بودم رو کمی تغییر دادم.

این خط رو :

if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))

به این شکل تغییر دادم :

if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (char.GetUnicodeCategory(c) == UnicodeCategory.OtherLetter))

در نهایت کلاس UrlHelper به این شکل شد :

public class UrlHelper
{
/// <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') || (char.GetUnicodeCategory(c) == UnicodeCategory.OtherLetter))
{
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();
}

public static string RemapInternationalCharToAscii(char c)
{
string s = c.ToString().ToLowerInvariant();
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 "";
}
}
}

prosoft01
سه شنبه 17 تیر 1399, 12:13 عصر
سلام یه سری به این لینک بزنید حتما جواب میگیرید

https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url

موفق باشید:چشمک:

hakan648
پنج شنبه 05 اسفند 1400, 20:06 عصر
ممنون بعد ۸ سال جواب دادید :)