Самый быстрый способ удалить пробелы в строке
Я пытаюсь получить несколько адресов электронной почты, разделенных "," внутри строки из таблицы базы данных, но он также возвращает мне пробелы, и я хочу быстро удалить эти пробелы.
Следующий код удаляет пробелы, но он также становится медленным, когда я пытаюсь получить большое количество адресов электронной почты в строке, например, до 30000, а затем пытаюсь удалить пробелы между ними. Для удаления этих пробелов требуется более четырех-пяти минут.
Regex Spaces =
new Regex(@"\s+", RegexOptions.Compiled);
txtEmailID.Text = MultipleSpaces.Replace(emailaddress),"");
Может ли кто-нибудь сказать мне, как я могу удалить пробелы в течение секунды даже для большого количества адресов электронной почты?
12 ответов
Я хотел бы создать собственный метод расширения, используя StringBuilder
, лайк:
public static string ExceptChars(this string str, IEnumerable<char> toExclude)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (!toExclude.Contains(c))
sb.Append(c);
}
return sb.ToString();
}
Использование:
var str = s.ExceptChars(new[] { ' ', '\t', '\n', '\r' });
или быть еще быстрее:
var str = s.ExceptChars(new HashSet<char>(new[] { ' ', '\t', '\n', '\r' }));
С версией hashset строка из 11 миллионов символов занимает менее 700 мс (и я в режиме отладки)
РЕДАКТИРОВАТЬ:
Предыдущий код является общим и позволяет исключить любой символ, но если вы хотите удалить только пробелы самым быстрым способом, вы можете использовать:
public static string ExceptBlanks(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
switch (c)
{
case '\r':
case '\n':
case '\t':
case ' ':
continue;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
}
РЕДАКТИРОВАТЬ 2:
как правильно указано в комментариях, правильный способ удалить все пробелы использует char.IsWhiteSpace
метод:
public static string ExceptBlanks(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if(!char.IsWhiteSpace(c))
sb.Append(c);
}
return sb.ToString();
}
Учитывая реализацию string.Replace
написано на C++ и часть времени исполнения CLR я готов поспорить
email.Replace(" ","").Replace("\t","").Replace("\n","").Replace("\r","");
будет самая быстрая реализация. Если вам нужны все типы пробелов, вы можете указать шестнадцатеричное значение, эквивалентное юникоду.
Тебе стоит попробовать String.Trim()
, Это обрежет все пробелы от начала до конца строки
Или вы можете попробовать этот метод из связанной темы: [ссылка]
public static unsafe string StripTabsAndNewlines(string s)
{
int len = s.Length;
char* newChars = stackalloc char[len];
char* currentChar = newChars;
for (int i = 0; i < len; ++i)
{
char c = s[i];
switch (c)
{
case '\r':
case '\n':
case '\t':
continue;
default:
*currentChar++ = c;
break;
}
}
return new string(newChars, 0, (int)(currentChar - newChars));
}
С linq вы можете сделать это просто:
emailaddress = new String(emailaddress
.Where(x=>x!=' ' && x!='\r' && x!='\n')
.ToArray());
Я не сравнивал это с подходами для построения строк, но гораздо быстрее, чем подходы на основе строк. Поскольку он не создает много копий строк (строка является неизменной, и ее прямое использование приводит к значительным проблемам с памятью и скоростью), поэтому он не будет использовать очень большую память и не будет замедлять скорость (за исключением одного дополнительного прохода через строка вначале).
Вы должны рассмотреть вопрос о замене пробелов в наборе записей в вашей хранимой процедуре или запросе, используя REPLACE( )
по возможности работайте и даже лучше исправляйте записи в БД, так как пробел в адресе электронной почты недопустим.
Как уже упоминалось, вам нужно будет профилировать различные подходы. Если вы используете Regex, вы должны минимально сделать его статической переменной уровня класса:
public static Regex MultipleSpaces = new Regex(@"\s+", RegexOptions.Compiled);
emailAddress.Where(x=>{ return x != ' ';}).ToString( )
Скорее всего, это приведет к перегрузке функций, хотя Microsoft может оптимизировать их для встроенных функций - снова профилирование даст вам ответ.
Самый эффективный метод - выделить буфер и копировать символ за символом в новый буфер и пропустить пробелы при этом. C# поддерживает указатели, так что вы можете использовать небезопасный код, выделять необработанный буфер и использовать арифметику указателей для копирования, как в C, и это настолько быстро, насколько это возможно. REPLACE( )
в SQL будет обрабатывать это так для вас.
Есть много разных способов, некоторые быстрее, чем другие:
public static string StripTabsAndNewlines(this string str) {
//string builder (fast)
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++) {
if ( ! Char.IsWhiteSpace(s[i])) {
sb.Append();
}
}
return sb.tostring();
//linq (faster ?)
return new string(str.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray());
//regex (slow)
return Regex.Replace(str, @"\s+", "")
}
Пожалуйста, используйте TrimEnd()
метод String
учебный класс. Вы можете найти отличный пример здесь.
string str = "Hi!! this is a bunch of text with spaces";
MessageBox.Show(new String(str.Where(c => c != ' ').ToArray()));
Я не тестировал производительность по этому поводу, но это проще, чем большинство других ответов.
var s1 = "\tstring \r with \t\t \nwhitespace\r\n";
var s2 = string.Join("", s1.Split());
Результат
stringwithwhitespace
string input =Yourinputstring;
string[] strings = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string value in strings)
{
string newv= value.Trim();
if (newv.Length > 0)
newline += value + "\r\n";
}
Самый быстрый и общий способ сделать это (разделители строк, вкладки также будут обработаны). Мощные средства Regex на самом деле не нужны для решения этой проблемы, но Regex может снизить производительность.
new string
(stringToRemoveWhiteSpaces
.Where
(
c => !char.IsWhiteSpace(c)
)
.ToArray<char>()
)
string s = " Your Text ";
string new = s.Replace(" ", string.empty);
// Output:
// "YourText"