конечный автомат может легко это сделать, но он, вероятно, излишним, если вам нужно только удалить пробелы
Адриан
Я добавил тест на различные способы сделать это в дублирующем вопросе stackoverflow.com/a/37592018/582061 . Regex был не самым быстрым способом сделать это.
Stian Standahl
Ответы:
470
string sentence ="This is a sentence with multiple spaces";RegexOptions options =RegexOptions.None;Regex regex =newRegex("[ ]{2,}", options);
sentence = regex.Replace(sentence," ");
У меня есть скопировать и вставить это, и это работает. Я действительно не люблю REgex, но на этот раз он спасает мне жизнь.
Покус
9
@ Достаточно написать комментарий, ИМО. // Этот блок заменяет несколько пробелов одним ... :)
paulwhit 15.10.08
6
На самом деле, RegEx излишне для этого.
Джоэл Коухорн
11
@Joel: не могу согласиться. Я действительно уверен, что этот способ более эффективен, чем ваш, для достаточно больших строк и может быть выполнен в одну строку. Где перегиб?
Конрад Рудольф
24
@ Код Оскара Джоэла не простой цикл для всех символов! Это скрытый вложенный цикл с квадратичным наихудшим случаем. Это регулярное выражение, напротив, является линейным, формирует только одну строку (= радикально уменьшенные затраты на выделение ресурсов по сравнению с кодом Джоэла) и, кроме того, движок может чертовски оптимизировать его (честно говоря, я сомневаюсь, что регулярное выражение .NET достаточно умный для этого, но теоретически это регулярное выражение может быть реализовано настолько дешево, что это даже не смешно: ему нужен только DFA с тремя состояниями, по одному переходу в каждом, и без дополнительной информации).
Конрад Рудольф
624
Мне нравится использовать:
myString =Regex.Replace(myString,@"\s+"," ");
Поскольку он будет перехватывать любые пробелы (например, табуляции, новые строки и т. Д.) И заменять их одним пробелом.
Небольшая модификация: Regex.Replace (source, @ "(\ s) \ s +", "$ 1"); Это вернет первый найденный пробельный тип. Так что, если у вас есть 5 вкладок, он вернет вкладку. Incase кто-то предпочитает это.
FB ten Kate
@radistao Ваша ссылка для замены строки Javascript, а не для C #.
Шива
1
@Shiva, / \ s \ s + / является стандартным оператором регулярных выражений POSIX и может быть преобразован / использован на любом языке с использованием собственного синтаксиса
radistao
4
В духе решения @ FBtenKate: Regex.Replace (source, @ "(\ s) \ 1+", "$ 1"); заменит несколько одинаковых последовательных символов одним.
Франсуа Бон
1
чтобы удалить начальные и конечные пробелы, вы должны использовать функцию Trim () с этим, например, var myString = Regex.Replace (myString, @ "\ s +", "") .Trim ();
Это более читабельно по сравнению с регулярными выражениями, я предпочитаю это больше, потому что мне не нужно изучать какой-то другой синтаксис
Майкл Бахиг
9
Мне это нравится, потому что ему не нужно
регулярное выражение
3
Это было бы неэффективно для больших строк.
DarcyThomas
3
Это также удаляет начальные и конечные пробелы.
Matzi
1
Я тоже предпочитаю этот ответ. Мой старый наставник обычно говорил: «Каждый раз, когда у тебя возникает проблема, ты думаешь, что Regex нужно решать, ну ... теперь у тебя ДВА проблемы» <wink>
Уильям Мадонна младший
38
Я думаю, что ответ Мэтта самый лучший, но я не верю, что он совершенно прав. Если вы хотите заменить символы новой строки, вы должны использовать:
RegexOptions.Multiline изменяет значение ^ и $, чтобы они соответствовали началу и концу каждой строки ($ = \ n) вместо всей многострочной строки. Поскольку \ s эквивалентно [\ f \ n \ r \ t \ v], новые строки следует заменять, даже если опция Multiline отключена.
SushiGuy
1
Ответ Мэтта уже охватил это. Я «верю», что 30 человек просто с завязанными глазами проголосовали за этот ответ :)
Это будет гораздо менее эффективно, чем регулярное выражение "{2,}", если строка содержит последовательности из 3 или более пробелов.
Ян Гойваертс
2
@JanGoyvaerts: даже с 10 пробелами регулярное выражение было медленнее, когда я сделал быстрый и грязный тест. При этом требуется всего одна гигантская подстрока, полная пробелов, чтобы полностью убить производительность цикла while. Справедливости ради, я использовал я использовал RegexOptions.Compiled, а не более медленный Regex.Replace.
Брайан
5
RegexOptions.Compiled добавляет много накладных расходов при компиляции регулярного выражения в IL. Не используйте его, если ваше приложение не будет использовать регулярное выражение достаточно часто или на достаточно больших строках, чтобы увеличение скорости совпадения компенсировало снижение скорости компиляции.
Ян Гойваертс
Это пример крайне неэффективного кода. ЛОЛ.
pcbabu
1
@pcbabu Это не так плохо, как кажется во многих случаях. Replace()Метод будет обрабатывать все вхождения двух пространств в данной строке, поэтому мы не зацикливание (и повторное выделение целой строки) для каждого экземпляра спаренных пробелов в строке. Одно новое распределение будет обрабатывать все из них. Мы перезапускаем цикл только тогда, когда было 3 или более пробелов вместе, что, вероятно, является более редким явлением для многих входных источников. Если вы можете показать, что это становится проблемой для ваших данных, тогда напишите конечный автомат, чтобы вставить символ за символом в новый построитель строк.
Джоэл Коухорн
21
Regex может быть довольно медленным даже с простыми задачами. Это создает метод расширения, который можно использовать для любого string.
publicstaticclassStringExtension{publicstaticStringReduceWhitespace(thisStringvalue){var newString =newStringBuilder();bool previousIsWhitespace =false;for(int i =0; i <value.Length; i++){if(Char.IsWhiteSpace(value[i])){if(previousIsWhitespace){continue;}
previousIsWhitespace =true;}else{
previousIsWhitespace =false;}
newString.Append(value[i]);}return newString.ToString();}}
Это будет использоваться как таковой:
string testValue ="This contains too much whitespace."
testValue = testValue.ReduceWhitespace();// testValue = "This contains too much whitespace."
Для тех, кто не любит Regex, вот метод, который использует StringBuilder:
publicstaticstringFilterWhiteSpaces(string input){if(input ==null)returnstring.Empty;StringBuilder stringBuilder =newStringBuilder(input.Length);for(int i =0; i < input.Length; i++){char c = input[i];if(i ==0|| c !=' '||(c ==' '&& input[i -1]!=' '))
stringBuilder.Append(c);}return stringBuilder.ToString();}
В моих тестах этот метод был в среднем в 16 раз быстрее с очень большим набором строк малого и среднего размера по сравнению со статически скомпилированным Regex. По сравнению с не скомпилированным или нестатичным Regex, это должно быть еще быстрее.
Имейте в виду, что он не удаляет начальные или конечные пробелы, только многократные появления таких.
Вы должны убедиться, что в вашей строке нет "()" или ") (" внутри. Или "wel()come to london)("становится "wel come to london". Вы можете попробовать использовать много скобок. Поэтому используйте ((((()))))вместо ()и )))))(((((вместо )(. Это все равно будет работать. Тем не менее, если строка содержит ((((()))))или )))))(((((, это не удастся.
nmit026
7
Это более короткая версия, которую следует использовать только в том случае, если вы делаете это только один раз, поскольку она создает новый экземпляр Regexкласса при каждом вызове.
temp =newRegex(" {2,}").Replace(temp," ");
Если вы не слишком знакомы с регулярными выражениями, вот краткое объяснение:
Команда {2,}regex ищет предшествующий ему символ и находит подстроки от 2 до неограниченного времени. Заменяет все матчи в строке температуры с пробелом. .Replace(temp, " ")
Если вы хотите использовать это несколько раз, вот лучший вариант, так как он создает регулярное выражение IL во время компиляции:
Предостережение: использование разделения, хотя и очень простое для понимания, может оказать неожиданно негативное влияние на производительность. Так как может быть создано много строк, вам придется следить за использованием памяти в случае, если вы обрабатываете большие строки этим методом.
Pac0
5
Утешает другие ответы, согласно Джоэлу, и, надеюсь, немного улучшается:
Одна из замечательных особенностей этого - то, что он работает с коллекциями, которые не являются строками, вызывая ToString () для элементов. Использование остается прежним:
//...string s =" 1 2 4 5".Split(" ".ToCharArray(),StringSplitOptions.RemoveEmptyEntries).Join(" ");
зачем создавать метод расширения? почему бы просто не использовать string.Join ()?
Эрик Шуновер
3
// Mysample stringstring str ="hi you are a demo";//Split the words based on white sapcevar demo= str .Split(' ').Where(s =>!string.IsNullOrWhiteSpace(s));//Join the values back and add a single space in between
str =string.Join(" ", demo);//output: string str ="hi you are a demo";
Я знаю, что это довольно старый, но наткнулся на это, пытаясь достичь почти того же. Нашел это решение в RegEx Buddy. Этот шаблон заменит все двойные пробелы одиночными пробелами, а также урежет начальные и конечные пробелы.
pattern:(?m:^+|+$|(){2,})
replacement: $1
Его немного сложно прочитать, поскольку мы имеем дело с пустым пространством, поэтому здесь снова с "пробелами", замененными на "_".
pattern:(?m:^_+|_+$|(_){2,})<-- don't use this, just for illustration.
Конструкция "(? M:" включает опцию "multi-line". Я обычно хотел бы включить все возможные варианты в сам шаблон, чтобы он был более автономным.
Многие ответы дают правильный результат, но для тех, кто ищет лучшие результаты, я улучшил ответ Ноланара (который был лучшим ответом для производительности) примерно на 10%.
publicstaticstringMergeSpaces(thisstring str){if(str ==null){returnnull;}else{StringBuilder stringBuilder =newStringBuilder(str.Length);int i =0;foreach(char c in str){if(c !=' '|| i ==0|| str[i -1]!=' ')
stringBuilder.Append(c);
i++;}return stringBuilder.ToString();}}
while word.contains(" ")//double space
word = word.Replace(" "," ");//replace double space by single space.
word = word.trim();//to remove single whitespces from start & end.
using System;
using System.Linq;
using System.Text;publicstaticclassStringExtension{publicstaticstringStripSpaces(thisstring s){return s.Aggregate(newStringBuilder(),(acc, c)=>{if(c !=' '|| acc.Length>0&& acc[acc.Length-1]!=' ')
acc.Append(c);return acc;}).ToString();}publicstaticvoidMain(){Console.WriteLine("\""+StringExtension.StripSpaces("1 Hello World 2 ")+"\"");}}
Ответы:
источник
Мне нравится использовать:
Поскольку он будет перехватывать любые пробелы (например, табуляции, новые строки и т. Д.) И заменять их одним пробелом.
источник
источник
Я думаю, что ответ Мэтта самый лучший, но я не верю, что он совершенно прав. Если вы хотите заменить символы новой строки, вы должны использовать:
источник
Другой подход, который использует LINQ:
источник
Это намного проще, чем все это:
источник
Replace()
Метод будет обрабатывать все вхождения двух пространств в данной строке, поэтому мы не зацикливание (и повторное выделение целой строки) для каждого экземпляра спаренных пробелов в строке. Одно новое распределение будет обрабатывать все из них. Мы перезапускаем цикл только тогда, когда было 3 или более пробелов вместе, что, вероятно, является более редким явлением для многих входных источников. Если вы можете показать, что это становится проблемой для ваших данных, тогда напишите конечный автомат, чтобы вставить символ за символом в новый построитель строк.Regex может быть довольно медленным даже с простыми задачами. Это создает метод расширения, который можно использовать для любого
string
.Это будет использоваться как таковой:
источник
источник
Для тех, кто не любит
Regex
, вот метод, который используетStringBuilder
:В моих тестах этот метод был в среднем в 16 раз быстрее с очень большим набором строк малого и среднего размера по сравнению со статически скомпилированным Regex. По сравнению с не скомпилированным или нестатичным Regex, это должно быть еще быстрее.
Имейте в виду, что он не удаляет начальные или конечные пробелы, только многократные появления таких.
источник
Вы можете просто сделать это в одном решении линии!
Вы можете выбрать другие скобки (или даже другие символы), если хотите.
источник
"wel()come to london)("
становится"wel come to london"
. Вы можете попробовать использовать много скобок. Поэтому используйте((((()))))
вместо()
и)))))(((((
вместо)(
. Это все равно будет работать. Тем не менее, если строка содержит((((()))))
или)))))(((((
, это не удастся.Это более короткая версия, которую следует использовать только в том случае, если вы делаете это только один раз, поскольку она создает новый экземпляр
Regex
класса при каждом вызове.Если вы не слишком знакомы с регулярными выражениями, вот краткое объяснение:
Команда
{2,}
regex ищет предшествующий ему символ и находит подстроки от 2 до неограниченного времени. Заменяет все матчи в строке температуры с пробелом..Replace(temp, " ")
Если вы хотите использовать это несколько раз, вот лучший вариант, так как он создает регулярное выражение IL во время компиляции:
источник
нет Regex, нет Linq ... удаляет начальные и конечные пробелы, а также сокращает любые вложенные сегменты нескольких пробелов в один пробел
результат: "0 1 2 3 4 5"
источник
Утешает другие ответы, согласно Джоэлу, и, надеюсь, немного улучшается:
Вы можете сделать это с
Regex.Replace()
:Или с
String.Split()
:источник
Я просто написал новый,
Join
который мне нравится, поэтому я решил, что я отвечу, с этим:Одна из замечательных особенностей этого - то, что он работает с коллекциями, которые не являются строками, вызывая ToString () для элементов. Использование остается прежним:
источник
источник
Я знаю, что это довольно старый, но наткнулся на это, пытаясь достичь почти того же. Нашел это решение в RegEx Buddy. Этот шаблон заменит все двойные пробелы одиночными пробелами, а также урежет начальные и конечные пробелы.
Его немного сложно прочитать, поскольку мы имеем дело с пустым пространством, поэтому здесь снова с "пробелами", замененными на "_".
Конструкция "(? M:" включает опцию "multi-line". Я обычно хотел бы включить все возможные варианты в сам шаблон, чтобы он был более автономным.
источник
Многие ответы дают правильный результат, но для тех, кто ищет лучшие результаты, я улучшил ответ Ноланара (который был лучшим ответом для производительности) примерно на 10%.
источник
Я могу удалить пробелы с этим
источник
Используйте шаблон регулярных выражений
источник
попробуйте этот метод
используйте это так:
источник
Вот небольшая модификация на Nolonar оригинальный ответ .
Проверка, является ли символ не просто пробелом, а пробелом, используйте это:
Он заменит любой символ пробела одним пробелом.
источник
Старая школа:
источник
Без использования регулярных выражений:
Можно использовать на коротких строках, но плохо работает на длинных строках с большим количеством пробелов.
источник
Смесь StringBuilder и Enumerable.Aggregate () в качестве метода расширения для строк:
Входные данные:
Вывод:
источник