Jak mogę zastąpić wiele spacji w ciągu tylko jedną spacją w C #?
Przykład:
1 2 3 4 5
byłoby:
1 2 3 4 5
Jak mogę zastąpić wiele spacji w ciągu tylko jedną spacją w C #?
Przykład:
1 2 3 4 5
byłoby:
1 2 3 4 5
Odpowiedzi:
string sentence = "This is a sentence with multiple spaces";
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
sentence = regex.Replace(sentence, " ");
Lubię używać:
myString = Regex.Replace(myString, @"\s+", " ");
Ponieważ wyłapuje biegi dowolnego rodzaju białych znaków (np. Tabulatory, znaki nowej linii itp.) I zastępuje je pojedynczą spacją.
string xyz = "1 2 3 4 5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));
Myślę, że odpowiedź Matta jest najlepsza, ale nie sądzę, żeby była słuszna. Jeśli chcesz zastąpić znaki nowej linii, musisz użyć:
myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);
To o wiele prostsze niż wszystko:
while(str.Contains(" ")) str = str.Replace(" ", " ");
Replace()
Metoda będzie obsługiwać wszystkie wystąpienia dwóch miejsc w danym ciągu znaków, więc nie jesteśmy w pętli (i realokacji cały łańcuch) dla każdej instancji sparowanych przestrzeni w ciąg. Jeden nowy przydział obsłuży je wszystkie. Ponownie uruchamiamy pętlę tylko wtedy, gdy są razem 3 lub więcej spacji, co może być rzadsze w przypadku wielu źródeł wejściowych. Jeśli możesz pokazać, że staje się to problemem dla twoich danych, to idź napisz maszynę stanu, aby wypychać znak po znaku do nowego programu budującego łańcuchy.
Regex może być powolny nawet przy prostych zadaniach. Tworzy to metodę rozszerzenia, której można użyć z dowolnej 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();
}
}
Byłby używany jako taki:
string testValue = "This contains too much whitespace."
testValue = testValue.ReduceWhitespace();
// testValue = "This contains too much whitespace."
myString = Regex.Replace(myString, " {2,}", " ");
Dla tych, którzy nie lubią Regex
, oto metoda, która wykorzystuje 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();
}
W moich testach ta metoda była średnio 16 razy szybsza przy bardzo dużym zestawie łańcuchów od małych do średnich, w porównaniu do regexu skompilowanego statycznie. W porównaniu z nieskompilowanym lub niestatycznym regeksem powinno to być jeszcze szybsze.
Pamiętaj, że nie usuwa początkowych ani końcowych spacji, a tylko ich wielokrotne wystąpienie.
Możesz to zrobić w jednym rozwiązaniu!
string s = "welcome to london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");
Możesz wybrać inne nawiasy (lub nawet inne znaki), jeśli chcesz.
"wel()come to london)("
się "wel come to london"
. Możesz spróbować użyć wielu nawiasów. Więc użyj ((((()))))
zamiast ()
i )))))(((((
zamiast )(
. Będzie nadal działać. Wciąż, jeśli ciąg zawiera ((((()))))
lub )))))(((((
, to się nie powiedzie
Jest to krótsza wersja, z której należy korzystać tylko wtedy, gdy robisz to tylko raz, ponieważ tworzy ona nową instancję Regex
klasy za każdym razem, gdy jest wywoływana.
temp = new Regex(" {2,}").Replace(temp, " ");
Jeśli nie znasz zbyt dobrze wyrażeń regularnych, oto krótkie wyjaśnienie:
{2,}
Sprawia, że przeszukiwanie regex dla znaku poprzedzającego go i wyszukuje podciągi między 2 i nieograniczony czas. Zastępuje wszystkie mecze w temp ciąg z kosmosu..Replace(temp, " ")
Jeśli chcesz użyć tego wielokrotnie, oto lepsza opcja, ponieważ tworzy ona wyrażenie regularne w czasie kompilacji:
Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");
bez Regex, bez Linq ... usuwa początkowe i końcowe spacje, a także redukuje osadzone segmenty wielu spacji do jednego spacji
string myString = " 0 1 2 3 4 5 ";
myString = string.Join(" ", myString.Split(new char[] { ' ' },
StringSplitOptions.RemoveEmptyEntries));
wynik: „0 1 2 3 4 5”
Pocieszając inne odpowiedzi, według Joela, i mam nadzieję, że nieco się poprawię:
Możesz to zrobić za pomocą Regex.Replace()
:
string s = Regex.Replace (
" 1 2 4 5",
@"[ ]{2,}",
" "
);
Lub z 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 (" ");
Właśnie napisałem nowy, Join
który mi się podoba, więc pomyślałem, że odpowiem ponownie:
public static string Join<T>(this IEnumerable<T> source, string separator)
{
return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}
Jedną z fajnych rzeczy jest to, że działa z kolekcjami, które nie są łańcuchami, wywołując ToString () na elementach. Użycie jest nadal takie samo:
//...
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";
Wiem, że to dość stare, ale natknąłem się na to, próbując osiągnąć prawie to samo. Znaleziono to rozwiązanie w RegEx Buddy. Ten wzór zastąpi wszystkie podwójne spacje pojedynczymi spacjami, a także przycina początkowe i końcowe spacje.
pattern: (?m:^ +| +$|( ){2,})
replacement: $1
Jest trochę trudny do odczytania, ponieważ mamy do czynienia z pustą przestrzenią, więc tutaj znowu jest to z „spacjami” zastąpionymi przez „_”.
pattern: (?m:^_+|_+$|(_){2,}) <-- don't use this, just for illustration.
Konstrukcja „(? M:” włącza opcję „wielu linii”. Zazwyczaj lubię zawrzeć dowolne opcje w obrębie samego wzorca, aby był bardziej samodzielny.
Wiele odpowiedzi zapewnia właściwą wydajność, ale dla tych, którzy szukają najlepszych wyników, poprawiłem odpowiedź Nolanara (która była najlepszą odpowiedzią na wydajność) o około 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();
}
}
Dzięki temu mogę usunąć białe spacje
while word.contains(" ") //double space
word = word.Replace(" "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.
wypróbuj tę metodę
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();
}
użyj tego w ten sposób:
string test = removeNestedWhitespaces("1 2 3 4 5".toCharArray());
Oto niewielkie modyfikacje na Nolonar oryginalnej odpowiedzi .
Aby sprawdzić, czy znak nie jest tylko spacją, ale dowolną spacją, użyj tego:
Zastąpi wiele znaków białych znaków pojedynczą spacją.
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();
}
Stary 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 " ) );
Bez użycia wyrażeń regularnych:
while (myString.IndexOf(" ", StringComparison.CurrentCulture) != -1)
{
myString = myString.Replace(" ", " ");
}
OK, aby używać na krótkich ciągach, ale będzie źle działać na długich ciągach z dużą ilością spacji.
Mieszanka StringBuilder i Enumerable.Aggregate () jako metody rozszerzenia ciągów:
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 ") + "\"");
}
}
Wejście:
"1 Hello World 2 "
Wynik:
"1 Hello World 2 "