Каков наилучший способ очистки URL? Я ищу такой URL
what_is_the_best_headache_medication
Мой текущий код
public string CleanURL(string str)
{
str = str.Replace("!", "");
str = str.Replace("@", "");
str = str.Replace("#", "");
str = str.Replace("$", "");
str = str.Replace("%", "");
str = str.Replace("^", "");
str = str.Replace("&", "");
str = str.Replace("*", "");
str = str.Replace("(", "");
str = str.Replace(")", "");
str = str.Replace("-", "");
str = str.Replace("_", "");
str = str.Replace("+", "");
str = str.Replace("=", "");
str = str.Replace("{", "");
str = str.Replace("[", "");
str = str.Replace("]", "");
str = str.Replace("}", "");
str = str.Replace("|", "");
str = str.Replace(@"\", "");
str = str.Replace(":", "");
str = str.Replace(";", "");
str = str.Replace(@"\", "");
str = str.Replace("'", "");
str = str.Replace("<", "");
str = str.Replace(">", "");
str = str.Replace(",", "");
str = str.Replace(".", "");
str = str.Replace("`", "");
str = str.Replace("~", "");
str = str.Replace("/", "");
str = str.Replace("?", "");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", " ");
str = str.Replace(" ", "_");
return str;
}
Как правило, лучше всего пойти с подходом с обычным выражением белого списка вместо удаления всех нежелательных символов, потому что вы определенно пропустите некоторые из них.
Ответы здесь прекрасны, но я лично не хотел полностью удалять умлаутов и персонажей с акцентом. Итак, окончательное решение, которое я придумал, выглядит так:
public static string CleanUrl(string value)
{
if (value.IsNullOrEmpty())
return value;
// replace hyphens to spaces, remove all leading and trailing whitespace
value = value.Replace("-", " ").Trim().ToLower();
// replace multiple whitespace to one hyphen
value = Regex.Replace(value, @"[\s]+", "-");
// replace umlauts and eszett with their equivalent
value = value.Replace("ß", "ss");
value = value.Replace("ä", "ae");
value = value.Replace("ö", "oe");
value = value.Replace("ü", "ue");
// removes diacritic marks (often called accent marks) from characters
value = RemoveDiacritics(value);
// remove all left unwanted chars (white list)
value = Regex.Replace(value, @"[^a-z0-9\s-]", String.Empty);
return value;
}
Используемый метод RemoveDiacritics
основан на ответе от Блэра Конрада:
public static string RemoveDiacritics(string value)
{
if (value.IsNullOrEmpty())
return value;
string normalized = value.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
foreach (char c in normalized)
{
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
sb.Append(c);
}
Encoding nonunicode = Encoding.GetEncoding(850);
Encoding unicode = Encoding.Unicode;
byte[] nonunicodeBytes = Encoding.Convert(unicode, nonunicode, unicode.GetBytes(sb.ToString()));
char[] nonunicodeChars = new char[nonunicode.GetCharCount(nonunicodeBytes, 0, nonunicodeBytes.Length)];
nonunicode.GetChars(nonunicodeBytes, 0, nonunicodeBytes.Length, nonunicodeChars, 0);
return new string(nonunicodeChars);
}
Надеюсь, что это поможет кому-то бросить вызов путем добавления URL-адресов и одновременного хранения умлаутов и друзей с их эквивалентом URL.
Регулярные выражения:
public string CleanURL(string str)
{
str = Regex.Replace(str, "[^a-zA-Z0-9 ]", "");
str = Regex.Replace(str, " +", "_");
return str;
}
(На самом деле не проверено, с головы.)
Позвольте мне объяснить:
Первая строка удаляет все, что не является буквенно-цифровым символом (верхний или нижний регистр) или пробелом. Вторая строка заменяет любую последовательность пробелов (1 или более, последовательно) с единственным подчеркиванием.
Вместо этого вам следует использовать регулярное выражение. Это намного эффективнее, чем вы пытаетесь сделать выше.
Подробнее о регулярных выражениях здесь.
То, как это делает stackoverflow, можно найти здесь:
оптимизирован для скорости ( "Это вторая версия, развернутая на 5 раз больше производительности" ) и заботясь о множестве специальных символов.
Или, немного более подробный, но это позволяет только буквенно-цифровые и пробелы (которые заменяются на "-" )
string Cleaned = String.Empty;
foreach (char c in Dirty)
if (((c >= 'a') && (c <= 'z')) ||
(c >= 'A') && (c <= 'Z') ||
(c >= '0') && (c <= '9') ||
(c == ' '))
Cleaned += c;
Cleaned = Cleaned.Replace(" ", "-");
Если вы хотите продолжить с помощью метода выше, я бы предложил перейти к StringBuilder по строке. Это связано с тем, что каждая из операций замены создает новую строку.
Я могу затянуть один кусок этого:
while (str.IndexOf(" ") > 0)
str = str.Replace(" ", " ");
... вместо вашего бесконечного числа заменяемых " "
. Но вы почти наверняка хотите использовать регулярное выражение.