Как заменить несколько пробелов в строке только одним пробелом в С#?
Пример:
1 2 3 4 5
:
1 2 3 4 5
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
tempo = regex.Replace(tempo, " ");
Мне нравится использовать:
myString = Regex.Replace(myString, @"\s+", " ");
Так как он будет улавливать прогоны любого вида пробелов (например, вкладки, новые строки и т.д.) и заменять их одним пробелом.
Я думаю, что ответ Мэтта - лучший, но я не верю, что это правильно. Если вы хотите заменить новые строки, вы должны использовать:
myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);
string xyz = "1 2 3 4 5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));
Другой подход, который использует LINQ:
var list = str.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
str = string.Join(" ", list);
Это намного проще, чем все:
while(str.Contains(" ")) str = str.Replace(" ", " ");
Regex может быть довольно медленным даже при простых задачах. Это создает метод расширения, который можно использовать с любого string
.
public static class StringExtension
{
public static String ReduceWhitespace(this String value)
{
var newString = new StringBuilder();
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."
myString = Regex.Replace(myString, " {2,}", " ");
Вы можете просто сделать это в одном линейном решении!
string s = "welcome to london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");
Если вы хотите, вы можете выбрать другие скобки (или даже другие символы).
"wel()come to london)("
становится "wel come to london"
. Вы можете попробовать использовать много скобок. Поэтому используйте ((((()))))
вместо ()
и )))))(((((
вместо )(
. Это все равно будет работать. Тем не менее, если строка содержит ((((()))))
или )))))(((((
, это не удастся.
Для тех, кому не нравится Regex
, вот метод, который использует StringBuilder
:
public static string FilterWhiteSpaces(string input)
{
if (input == null)
return string.Empty;
StringBuilder stringBuilder = new StringBuilder(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, это должно быть еще быстрее.
Имейте в виду, что он не удаляет ведущие или конечные пробелы, только несколько вхождений таких.
Это более короткая версия, которую следует использовать, только если вы делаете это только один раз, поскольку каждый раз, когда она вызывается, создается новый экземпляр класса Regex
.
temp = new Regex(" {2,}").Replace(temp, " ");
Если вы не слишком знакомы с регулярными выражениями, здесь короткое объяснение:
{2,}
выполняет поиск регулярного выражения для символа, предшествующего ему, и находит подстроки между 2 и неограниченными временами. .Replace(temp, " ")
заменяет все совпадения в строке temp пробелом.
Если вы хотите использовать это несколько раз, вот лучший вариант, так как он создает регулярное выражение IL во время компиляции:
Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");
no Regex, no Linq... удаляет ведущие и конечные пробелы, а также уменьшает любые вложенные множественные сегменты пространства в одно пространство
string myString = " 0 1 2 3 4 5 ";
myString = string.Join(" ", myString.Split(new char[] { ' ' },
StringSplitOptions.RemoveEmptyEntries));
результат: "0 1 2 3 4 5"
Утешение других ответов, за Джоэла, и, надеюсь, немного улучшится, когда я пойду:
Вы можете сделать это с помощью Regex.Replace()
:
string s = Regex.Replace (
" 1 2 4 5",
@"[ ]{2,}",
" "
);
Или с String.Split()
:
static class StringExtensions
{
public static string Join(this IList<string> value, string separator)
{
return string.Join(separator, value.ToArray());
}
}
//...
string s = " 1 2 4 5".Split (
" ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
).Join (" ");
Я знаю, что это довольно старый, но натолкнулся на это, пытаясь выполнить почти то же самое. Нашел это решение в RegEx Buddy. Этот шаблон заменит все двойные пробелы на отдельные пробелы, а также нарисует ведущие и конечные пробелы.
pattern: (?m:^ +| +$|( ){2,})
replacement: $1
Его немного трудно читать, так как мы имеем дело с пустым пространством, так что здесь снова с "пробелами" заменено "_".
pattern: (?m:^_+|_+$|(_){2,}) <-- don't use this, just for illustration.
Конструкция "(? m:" включает параметр "многострочный". Обычно мне нравится включать любые параметры, которые я могу в самом шаблоне, поэтому он более автономный.
Я могу удалить пробелы с помощью этого
while word.contains(" ") //double space
word = word.Replace(" "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.
попробуйте этот метод
private string removeNestedWhitespaces(char[] st)
{
StringBuilder sb = new StringBuilder();
int indx = 0, length = st.Length;
while (indx < length)
{
sb.Append(st[indx]);
indx++;
while (indx < length && st[indx] == ' ')
indx++;
}
return sb.ToString();
}
используйте его следующим образом:
string test = removeNestedWhitespaces("1 2 3 4 5".toCharArray());
Я только что написал новый Join
, который мне нравится, поэтому я подумал, что я бы снова ответил:
public static string Join<T>(this IEnumerable<T> source, string separator)
{
return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}
Одна из интересных вещей в этом заключается в том, что она работает с коллекциями, которые не являются строками, вызывая ToString() для элементов. Использование остается тем же:
//...
string s = " 1 2 4 5".Split (
" ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
).Join (" ");
Многие ответы дают правильный результат, но для тех, кто ищет лучшие результаты, я улучшил ответ Nolanar (который был лучшим ответом на производительность) примерно на 10 %.
public static string MergeSpaces(this string str)
{
if (str == null)
{
return null;
}
else
{
StringBuilder stringBuilder = new StringBuilder(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 (myString.IndexOf(" ", StringComparison.CurrentCulture) != -1)
{
myString = myString.Replace(" ", " ");
}
ОК для использования на коротких строках, но будет плохо работать на длинных строках с большим количеством пробелов.
Старый skool:
string oldText = " 1 2 3 4 5 ";
string newText = oldText
.Replace(" ", " " + (char)22 )
.Replace( (char)22 + " ", "" )
.Replace( (char)22 + "", "" );
Assert.That( newText, Is.EqualTo( " 1 2 3 4 5 " ) );
(char)22