Jak usunąć znaki nowego wiersza z ciągu?


181

Mam ciąg w następującym formacie

string s = "This is a Test String.\n   This is a next line.\t This is a tab.\n'

Chcę usunąć wszystkie wystąpienia \ni \rz powyższego ciągu.

Próbowałem, string s = s.Trim(new char[] {'\n', '\r'});ale to nie pomogło.

Odpowiedzi:


321

Lubię używać wyrażeń regularnych. W takim przypadku możesz:

string replacement = Regex.Replace(s, @"\t|\n|\r", "");

Wyrażenia regularne nie są tak popularne w świecie .NET, jak w językach dynamicznych, ale zapewniają dużą moc manipulowania ciągami znaków.


To było dla mnie zdecydowanie najlepsze rozwiązanie. Płynne połączenie tego języka C # i javascript było wszystkim, czego potrzebowałem, aby rozwiązać mój problem.
Joe Brunscheon

Miałem podobny problem, w którym musiałem również usunąć znaki nowej linii z mojego ciągu. Próbowałem to zrobić za pomocą string.Replace, nie działa. Kiedy użyłem Regex.Replace z dokładnie tym samym ciągiem wyrażenia regularnego co parametr, zadziałało. Dzięki.
wystąpienie

8
Zachowaj ostrożność, jeśli używasz tego w pętli, która przetwarza ponad 1 mln elementów. Regex jest znacznie wolniejszy niż zwykły String. Zastąp
Nick

Przykładowy kod usuwa również tabulatory \ t, o co nie chodzi.
Michael Freidgeim

71

Chcesz użyć, String.Replaceaby usunąć znak.

s = s.Replace("\n", String.Empty);
s = s.Replace("\r", String.Empty);
s = s.Replace("\t", String.Empty);

Zauważ, że String.Trim(params char[] trimChars)usuwa tylko początkowe i końcowe znaki trimCharsz instancji wywołanej.

Możesz stworzyć metodę rozszerzającą, która pozwoli uniknąć problemów z wydajnością, które wynikają z powyższego tworzenia wielu tymczasowych ciągów:

static string RemoveChars(this string s, params char[] removeChars) {
    Contract.Requires<ArgumentNullException>(s != null);
    Contract.Requires<ArgumentNullException>(removeChars != null);
    var sb = new StringBuilder(s.Length);
    foreach(char c in s) { 
        if(!removeChars.Contains(c)) {
            sb.Append(c);
        }
    }
    return sb.ToString();
}

8
Zauważ, że to podejście spowoduje utworzenie dwóch pośrednich obiektów łańcuchowych. W zależności od rozmiaru ciągu może to mieć znaczące konsekwencje dla wydajności i zużycia pamięci.
cdhowie


15

Jeśli ważna jest szybkość i niskie zużycie pamięci, zrób coś takiego:

var sb = new StringBuilder(s.Length);

foreach (char i in s)
    if (i != '\n' && i != '\r' && i != '\t')
        sb.Append(i);

s = sb.ToString();

Tak, też bym to zrobił (w metodzie rozszerzenia). Zawsze dobrze jest używać StringBuilder. +1
RPM1984

4
„Zawsze dobrze jest używać StringBuilder” <Nie jestem profesjonalistą, ale to nie do końca prawda. Ten artykuł autorstwa Jeffa Atwooda zapewnia zabawny wgląd w manipulowanie ciągami / konkatenację i ostatecznie optymalizację.
Phil Cooper

5

po prostu to zrób

s = s.Replace("\n", String.Empty).Replace("\t", String.Empty).Replace("\r", String.Empty);

3

Podejście LINQ:

string s = "This is a Test String.\n   This is a next line.\t This is a tab.\n'";

string s1 = String.Join("", s.Where(c => c != '\n' && c != '\r' && c != '\t'));

1
Jest to użycie ogólnego przeciążenia, string.Joinktóre wywoła ToStringkażde charzwrócone przez zapytanie. Lepiej jest po prostu przekazać wyniki zapytania do stringkonstruktora. s1 = new string(s.Where(....).ToArrary());
juharr

0

Właściwy wybór naprawdę zależy od tego, jak duży jest ciąg wejściowy oraz jakie są wymagania dotyczące mocy i pamięci, ale użyłbym wyrażenia regularnego, takiego jak

string result = Regex.Replace(s, @"\r\n?|\n|\t", String.Empty);

Lub jeśli musimy wielokrotnie zastosować tę samą zamianę, lepiej jest użyć skompilowanej wersji dla Regex

var regex = new Regex(@"\r\n?|\n|\t", RegexOptions.Compiled); 
string result = regex.Replace(s, String.Empty);

UWAGA: różne scenariusze wymagają różnych podejść, aby osiągnąć najlepszą wydajność i minimalne zużycie pamięci


0

Cóż ... Chciałbym, żebyś zrozumiał bardziej szczegółowe obszary przestrzeni. \tjest właściwie dobrana jako przestrzeń pozioma, a nie pionowa. (przetestuj wkładanie\t w Notatniku)

Jeśli używasz języka Java, po prostu użyj \v. Zobacz odniesienie poniżej.

\h - Poziomy biały znak:

[\t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]

\v - Pionowy biały znak:

[\n\x0B\f\r\x85\u2028\u2029]

Ale zdaję sobie sprawę, że używasz .NET. Więc moja odpowiedź na zastąpienie każdej pionowej przestrzeni jest ...

string replacement = Regex.Replace(s, @"[\n\u000B\u000C\r\u0085\u2028\u2029]", "");

Wygląda na to, że jest odpowiedzią na inne pytanie ... a także brakuje rzeczywistego odniesienia ...
Alexei Levenkov

-4

Możesz użyć, Trimjeśli chcesz usunąć z początku i końca.

string stringWithoutNewLine = "\n\nHello\n\n".Trim();

-6

FYI,

Trim () już to robi.

Poniższy przykład LINQPad:

void Main()
{
    var s = " \rsdsdsdsd\nsadasdasd\r\n ";
    s.Length.Dump();
    s.Trim().Length.Dump();
}

Wyjścia:

23
18

5
To nie usuwa \ nw środku.
FlappySocks
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.