Самый быстрый способ удалить пробелы в строке
Я пытаюсь получить несколько адресов электронной почты, разделенных символом "," внутри строки из таблицы базы данных, но также возвращает мне пробелы, и я хочу быстро удалить пробелы.
В следующем коде удаляются пробелы, но он также замедляется, когда я пытаюсь получить большое количество адресов электронной почты в строке, например, до 30000, а затем попытаться удалить пробелы между ними. Чтобы удалить эти пробелы, требуется более четырех-пяти минут.
Regex Spaces =
new Regex(@"\s+", RegexOptions.Compiled);
txtEmailID.Text = MultipleSpaces.Replace(emailaddress),"");
Может ли кто-нибудь рассказать мне, как я могу удалить пробелы в течение секунды даже для большого количества адресов электронной почты?
Ответы
Ответ 1
Я бы построил собственный метод расширения с помощью 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 мс (и я в режиме отладки)
EDIT:
Предыдущий код является общим и позволяет исключить любой char, но если вы хотите удалить только пробелы самым быстрым способом, вы можете использовать:
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();
}
Ответ 2
Учитывая, что реализация string.Replace
написана на С++ и часть
будет самой быстрой реализацией. Если вам нужен каждый тип пробела, вы можете указать шестнадцатеричное значение эквивалента юникода.
Ответ 3
Вы должны попробовать String.Trim()
. Он будет обрезать все пробелы от начала до конца строки
Или вы можете попробовать этот метод из связанной темы: [link]
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));
}
Ответ 4
С помощью linq вы можете сделать это просто:
emailaddress = new String(emailaddress
.Where(x=>x!=' ' && x!='\r' && x!='\n')
.ToArray());
Я не сравнивал его с подстроками stringbuilder, но намного быстрее, чем строковые подходы.
Поскольку он не создает много копий строк (строка неизменна и ее использование напрямую приводит к резкому увеличению памяти и скорости), поэтому она не будет использовать очень большую память и не будет замедлять скорость (за исключением одного дополнительного прохода через строка сначала).
Ответ 5
emailaddress.Replace(" ", string.empty);
Ответ 6
Пожалуйста, используйте метод TrimEnd()
класса String
. Вы можете найти отличный пример здесь.
Ответ 7
Есть много разных способов, некоторые быстрее других:
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+", "")
}
Ответ 8
Вам следует рассмотреть возможность замены пробелов в наборе записей в вашей хранимой процедуре или запросе с помощью функции REPLACE( )
, если это возможно, и даже лучше исправить ваши записи БД, так как пространство в адресе электронной почты в любом случае недействительно.
Как уже упоминалось другими, вам нужно будет проанализировать различные подходы. Если вы используете Regex, вы должны минимально сделать его статической переменной на уровне класса:
public static Regex MultipleSpaces = new Regex(@"\s+", RegexOptions.Compiled);
emailAddress.Where(x=>{ return x != ' ';}).ToString( )
, вероятно, будет иметь накладные расходы, хотя он может быть оптимизирован для встроенного Microsoft - повторное профилирование даст вам ответ.
Наиболее эффективным методом было бы распределить буфер и скопировать символ по символу в новый буфер и пропустить пробелы, как вы это делаете. С# поддерживает указатели, поэтому вы можете использовать небезопасный код, выделять необработанный буфер и использовать арифметику указателя для копирования, как в C, и это так быстро, как это возможно. REPLACE( )
в SQL будет обрабатывать его как это для вас.
Ответ 9
string str = "Hi!! this is a bunch of text with spaces";
MessageBox.Show(new String(str.Where(c => c != ' ').ToArray()));
Ответ 10
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";
}
Ответ 11
string s = " Your Text ";
string new = s.Replace(" ", string.empty);
// Output:
// "YourText"
Ответ 12
Самый быстрый и общий способ сделать это (также будут обрабатываться терминаторы строк, вкладки). Regex мощные средства действительно не нужны для решения этой проблемы, но Regex может снизить производительность.
new string
(stringToRemoveWhiteSpaces
.Where
(
c => !char.IsWhiteSpace(c)
)
.ToArray<char>()
)