Як я можу замінити декілька пробілів у рядку лише одним пробілом у C #?
Приклад:
1 2 3 4 5
було б:
1 2 3 4 5
Як я можу замінити декілька пробілів у рядку лише одним пробілом у C #?
Приклад:
1 2 3 4 5
було б:
1 2 3 4 5
Відповіді:
string sentence = "This is a sentence with multiple spaces";
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
sentence = regex.Replace(sentence, " ");
Мені подобається використовувати:
myString = Regex.Replace(myString, @"\s+", " ");
Оскільки він буде вловлювати пробіли будь-якого пробілу (наприклад, вкладки, нові рядки тощо) та замінить їх єдиним пробілом.
string xyz = "1 2 3 4 5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));
Я думаю, що відповідь Метта найкраща, але я не вірю, що це цілком правильно. Якщо ви хочете замінити нові рядки, ви повинні використовувати:
myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);
Це набагато простіше, ніж усе, що:
while(str.Contains(" ")) str = str.Replace(" ", " ");
Replace()
Метод буде обробляти всі входження двох просторів в цьому рядку, тому ми не зациклення (і повторне виділення цілого рядка) для кожного екземпляра спарених прогалин в рядку. Один новий розподіл буде обробляти всі вони. Ми повторно запускаємо цикл лише тоді, коли були 3 або більше пробілів разом, що, швидше за все, буде рідкісним явищем для багатьох вхідних джерел. Якщо ви зможете показати, що це стає проблемою для ваших даних, тоді перейдіть до запису стану машини, щоб підштовхнути персонажів за символом до нового струнобудівника.
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,}", " ");
Для тих, хто не любить 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, це має бути ще швидшим.
Майте на увазі, що він не видаляє провідні чи кінцеві пробіли, а лише кілька випадків таких.
Ви можете просто зробити це в одному рядковому рішенні!
string s = "welcome to london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");
Ви можете вибрати інші дужки (або навіть інші символи), якщо вам подобається.
"wel()come to london)("
стає "wel come to london"
. Ви можете спробувати використовувати багато дужок. Тому використовуйте ((((()))))
замість цього, ()
а не )))))(((((
замість нього )(
. Він все одно буде працювати. Все ж, якщо рядок містить ((((()))))
або )))))(((((
, це не вдасться
Це більш коротка версія, яку слід використовувати лише якщо ви робите це лише один раз, оскільки вона створює новий екземпляр Regex
класу кожного разу, коли він викликається.
temp = new Regex(" {2,}").Replace(temp, " ");
Якщо ви не надто знайомі з регулярними виразами, ось коротке пояснення:
{2,}
Робить пошук регулярних виразів для характеру попереднього, і знаходять подстроки між 2 і необмеженою кількістю раз. Замінює всі матчі в рядку температури з пропуском..Replace(temp, " ")
Якщо ви хочете скористатися цим декількома разів, ось кращий варіант, оскільки він створює IL-регулярний вираз під час компіляції:
Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");
ні Regex, ні 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 (" ");
Я щойно написав нове, 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 (" ");
// Mysample string
string str ="hi you are a demo";
//Split the words based on white sapce
var 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:" дозволяє включити "багаторядковий" варіант. Я, як правило, люблю включати будь-які варіанти, які я можу, до самого шаблону, щоб він був більш самостійним.
Багато відповідей дають правильний результат, але для тих, хто шукає найкращих вистав, я покращив відповідь Ноланара (яка була найкращою відповіддю для виконання) приблизно на 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 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++;
if(sb.Length > 1 && sb[0] != ' ')
sb.Append(' ');
}
return sb.ToString();
}
використовуйте його так:
string test = removeNestedWhitespaces("1 2 3 4 5".toCharArray());
Ось невелика модифікація на Nolonar оригінальну відповідь .
Перевіряючи, чи персонаж не просто пробіл, а будь-який пробіл, використовуйте це:
Він замінить будь-який кілька символів пробілу одним пробілом.
public static string FilterWhiteSpaces(string input)
{
if (input == null)
return string.Empty;
var stringBuilder = new StringBuilder(input.Length);
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (i == 0 || !char.IsWhiteSpace(c) || (char.IsWhiteSpace(c) &&
!char.IsWhiteSpace(strValue[i - 1])))
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
Старий скол:
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 " ) );
Без використання регулярних виразів:
while (myString.IndexOf(" ", StringComparison.CurrentCulture) != -1)
{
myString = myString.Replace(" ", " ");
}
Добре використовувати для коротких рядків, але погано виконуватиме довгі рядки з великою кількістю пробілів.
Мікс StringBuilder і Enumerable.Aggregate () як метод розширення для рядків:
using System;
using System.Linq;
using System.Text;
public static class StringExtension
{
public static string StripSpaces(this string s)
{
return s.Aggregate(new StringBuilder(), (acc, c) =>
{
if (c != ' ' || acc.Length > 0 && acc[acc.Length-1] != ' ')
acc.Append(c);
return acc;
}).ToString();
}
public static void Main()
{
Console.WriteLine("\"" + StringExtension.StripSpaces("1 Hello World 2 ") + "\"");
}
}
Вхід:
"1 Hello World 2 "
Вихід:
"1 Hello World 2 "