Zamień podziały linii w ciągu C #


512

Jak mogę zastąpić podziały wiersza w ciągu w C #?


2
Powiedz nam więcej: czym jest dla Ciebie „przełamanie linii”? Czym chcesz je zastąpić?
Jay Bazuzi

ha ha. Sprawdzałem to samo dla java, kiedy dowiedziałem się, że System.getProperty („line.separator”) był ciekawym odpowiednikiem w języku C #. twój post pomógł mi.
Ravisha

Odpowiedzi:


715

Użyj zamień na Environment.NewLine

myString = myString.Replace(System.Environment.NewLine, "replacement text"); //add a line terminating ;

Jak wspomniano w innych postach, jeśli ciąg pochodzi z innego środowiska (OS), należy zastąpić implementację nowych znaków kontrolnych wiersza w tym środowisku .


8
Po pierwsze, nie działało to dla mnie. Po kilku badaniach znalazłem rozwiązanie: musiałem użyć „using System”; lub „System.Environment.NewLine”
Smolla

12
Nie usunięto wszystkich znaków nowej linii. Wypróbuj ten ciąg „\ n \ r \ nTo jest moja wiadomość \ r \ n \ n \ r \ n. \ N \ n \ r \ n”
Shakti Prakash Singh

13
Ogólnie podoba mi się to rozwiązanie. Należy jednak pamiętać, że nawet w tym samym systemie operacyjnym rzeczywiste znaki nowej linii mogą się nie zgadzać. Zdarzyło mi się, dlaczego przetwarzanie zwróciło SQL. Nowe linie to \ n, podczas gdy Environment.NewLine to \ r \ n. W rezultacie nic nie zostało dopasowane, więc nowe linie pozostały.
Dono

@Dono> skąd pochodzą dane SQL? Prawdopodobnie ze źródła zewnętrznego zajmującego się nowymi liniami w sposób uniksowy. To jest problem z formatem danych, nie z systemem operacyjnym ani z tą metodą ...
Laurent S.

Powinna to być jedna z metod statycznych klasy String. Sam .NET powinien być w stanie wykryć format podziałów linii źródłowej w ciągu znaków i przekonwertować go na format Environment.NewLine \ r \ n ...
Dean Kuga

442

Rozwiązania opublikowane do tej pory albo tylko zastępują, Environment.NewLinealbo zawodzą, jeśli ciąg zastępujący zawiera podziały wiersza, ponieważ wywołują string.Replacewiele razy.

Oto rozwiązanie, które wykorzystuje wyrażenie regularne do wykonania wszystkich trzech zamian w jednym przejściu ciągu. Oznacza to, że ciąg zastępujący może bezpiecznie zawierać podziały linii.

string result = Regex.Replace(input, @"\r\n?|\n", replacementString);

3
więc twoje powiedzenie wykonując Regex.Replace (input, @ "[\ r \ n] +", replaceString) nie wykonałoby tego samego zadania?
flamebaud

7
@flamebaud Nie, to dałoby inny wynik, jeśli istnieje wiele podziałów linii w rzędzie. „\ r \ n? | \ n” zastąpi każdy podział linii, podczas gdy „[\ r \ n] +” wykona pojedyncze zastąpienie dowolnej liczby podziałów linii.
David Hammond

Dla tych, którzy martwią się wieloma przerwami w linii: / (\ r \ n? | \ N) / gm
BobbyA

4
Jest to właściwie prawidłowe rozwiązanie, jeśli chcesz usunąć podział linii w ciągu, który może pochodzić z innego systemu operacyjnego. Dobrym przykładem jest formatowanie JSON. +1
Bastien Vandamme

1
Jeśli nie zostanie użyty pełny ciąg (przedrostek @), musisz mieć dwa ukośniki w wierszu wszędzie tam, gdzie jest używany, więc odpowiedź @mark_byers powyżej jest nadal poprawna. Prefiks @ sprawia, że ​​ukośnik odwrotny jest częścią ciągu, którym musi być Regex, aby używał go jako znaku zmiany znaczenia.
Kirk Liemohn,

173

Aby rozszerzyć odpowiedź The.Anyi.9, powinieneś również zdawać sobie sprawę z różnych typów ogólnego łamania linii . W zależności od tego, skąd pochodzi Twój plik, możesz sprawdzić, czy złapałeś wszystkie alternatywy ...

string replaceWith = "";
string removedBreaks = Line.Replace("\r\n", replaceWith).Replace("\n", replaceWith).Replace("\r", replaceWith);

powinienem zacząć ...


6
Najpierw bardziej spodobało mi się środowisko, ale jeśli String nie pochodzi z systemu, w którym działa, nie będzie działać. +1
Flo

1
nie Line.Replace("\n", replaceWith).Replace("\r", replaceWith);wystarczy?
Thomas Ayoub,

5
Nie, ponieważ jeśli masz \r\n, skończysz z ciągiem zastępczym dwa razy - nie idealnie.
ZombieSheep

1
Nie potrzebujesz literałów łańcuchowych? string removeBreaks = Line.Replace (@ "\ r \ n", replaceWith) .Replace (@ "\ n", replaceWith) .Replace (@ "\ r", replaceWith);
Shawn Dotey,

2
@ShawnDotey nie trzeba, chcemy zastąpić znaki kontrolne, a nie sekwencje odwrotnego ukośnika i litery.
N. Kudryavtsev

38

Chciałbym użyć Environment.Newline, gdy chciałem wstawić nowy wiersz dla ciągu, ale nie do usunięcia wszystkich nowych wierszy z ciągu.

W zależności od platformy możesz mieć różne typy znaków nowej linii, ale nawet na tej samej platformie często stosuje się różne rodzaje znaków nowej linii. W szczególności w przypadku formatów plików i protokołów.

string ReplaceNewlines(string blockOfText, string replaceWith)
{
    return blockOfText.Replace("\r\n", replaceWith).Replace("\n", replaceWith).Replace("\r", replaceWith);
}

Jest to jedyna rzecz, która działała dla mnie, gdy chciałem zwinąć pobrany kod strony internetowej w jednym wierszu (aby ułatwić wzorce wyrażeń regularnych).
Paw Baltzersen,

Całkowicie zgadzam się z Brianem R. Bondy. Rozwiązanie oferowane przez Corina i tak wysoko ocenione jest przynajmniej bardzo naiwne.
Califf

18

Jeśli twój kod ma działać w różnych środowiskach, rozważyłbym użycie Environment.NewLinestałej, ponieważ jest ona specyficznie newlineużywana w określonym środowisku.

line = line.Replace(Environment.NewLine, "newLineReplacement");

Jeśli jednak otrzymujesz tekst z pliku pochodzącego z innego systemu, może to nie być poprawna odpowiedź i powinieneś zastąpić dowolną stałą nowego wiersza używaną w innym systemie. Zazwyczaj będzie to \nlub \r\n.


Musisz ponownie przypisać ją do oryginalnej zmiennej, ponieważ zamiana nie występuje na miejscu.
tvanfosson

@driss Chciałbym wiedzieć, jak wybrać właściwą nową stałą linii, gdy nie masz pojęcia, z jakiego systemu pochodzi plik ... to rozwiązanie naprawdę wydaje się UNIWERSALNE.
Califf

14

Nie zapominaj, że replace nie wykonuje zamiany w ciągu, ale zwraca nowy ciąg z zastąpionymi znakami. Poniższe spowoduje usunięcie podziałów linii (nie zastąpi ich). Użyłbym metody @Briana R. Bondy'ego, jeśli zastąpiłbym je czymś innym, być może opakowanym jako metoda rozszerzenia. Pamiętaj, aby najpierw sprawdzić wartości zerowe przed wywołaniem funkcji Replace lub podanych metod rozszerzenia.

string line = ...

line = line.Replace( "\r", "").Replace( "\n", "" );

Jako metody rozszerzenia:

public static class StringExtensions
{
   public static string RemoveLineBreaks( this string lines )
   {
      return lines.Replace( "\r", "").Replace( "\n", "" );
   }

   public static string ReplaceLineBreaks( this string lines, string replacement )
   {
      return lines.Replace( "\r\n", replacement )
                  .Replace( "\r", replacement )
                  .Replace( "\n", replacement );
   }
}

nie mogę mieć ''w C # - nie ma czegoś takiego jak pusty znak. będzie '\0'działać zamiast tego?
Shevek

1
@ Shevek - po prostu użyłem niewłaściwych cytatów. Musiałem robić sporo javascript w dniu, w którym odpowiedziałem na to.
tvanfosson

@Califf - jest równoważny, a nie lepszy.
tvanfosson

2
błąd, który popełniłeś tutaj, dowodzi, że JEST lepszy. Większość firm, dla których pracowałem, ma swój standard kodowania - NIE UŻYWAJ LITERALI HARDCODED.
Califf

2
@Califf „błąd”, który popełniłem, nie zostałby popełniony w środowisku IDE z Intellisense ani nie zostałby skompilowany. Jeśli uważasz, że string.Emptyjest to lepsze, skorzystaj z niego.
tvanfosson

10

Aby upewnić się, że wszystkie możliwe sposoby podziału linii (Windows, Mac i Unix) zostały zastąpione, należy użyć:

string.Replace("\r\n", "\n").Replace('\r', '\n').Replace('\n', 'replacement');

i w tej kolejności, aby nie robić dodatkowych podziałów linii, gdy znajdziesz jakąś kombinację znaków kończących linię.


8

jeśli chcesz „wyczyścić” nowe linie, najlepiej jest użyć komentarza Flameba przy użyciu wyrażenia regularnego @"[\r\n]+".

using System;
using System.Text.RegularExpressions;

class MainClass {
  public static void Main (string[] args) {
    string str = "AAA\r\nBBB\r\n\r\n\r\nCCC\r\r\rDDD\n\n\nEEE";

    Console.WriteLine (str.Replace(System.Environment.NewLine, "-"));
    /* Result:
    AAA
    -BBB
    -
    -
    -CCC


    DDD---EEE
    */
    Console.WriteLine (Regex.Replace(str, @"\r\n?|\n", "-"));
    // Result:
    // AAA-BBB---CCC---DDD---EEE

    Console.WriteLine (Regex.Replace(str, @"[\r\n]+", "-"));
    // Result:
    // AAA-BBB-CCC-DDD-EEE
  }
}

Najlepsza odpowiedź na zastąpienie nowych linii w większości przypadków.
Shahbaz Ahmad

Dzięki za ten przydatny przykładowy kod. Naprawiono mnie za pomocą tego sytnax: Regex.Replace (str, @ "[\ r \ n] +", "-")
Sedat Kumcu

6

Musiałem zastąpić \r\nrzeczywistym znakiem powrotu karetki i przesunięciem wiersza i zastąpić \tfaktyczną tabulatorem. Więc wpadłem na następujące:

public string Transform(string data)
{
    string result = data;
    char cr = (char)13;
    char lf = (char)10;
    char tab = (char)9;

    result = result.Replace("\\r", cr.ToString());
    result = result.Replace("\\n", lf.ToString());
    result = result.Replace("\\t", tab.ToString());

    return result;
}

6

Dlaczego nie oba?

string ReplacementString = "";

Regex.Replace(strin.Replace(System.Environment.NewLine, ReplacementString), @"(\r\n?|\n)", ReplacementString);

Uwaga: Zamień strinna nazwę swojego ciągu wejściowego.



2

Użyj metody .Replace ()

Line.Replace("\n", "whatever you want to replace with");

2

Najlepszym sposobem na bezpieczne zastąpienie łamania linii jest

yourString.Replace("\r\n","\n") //handling windows linebreaks
.Replace("\r","\n")             //handling mac linebreaks

które powinny generować ciąg z \ n (np. linefeed) jako podziałami linii. ten kod jest także przydatny do naprawy mieszanych podziałów linii.


2

Jako nowej linii może być ograniczona \n, \ra \r\nprzede będziemy wymieniać \ri \r\nz \n, a dopiero potem podzielonego ciąg danych.

Do parseCSVmetody powinny przejść następujące wiersze :

function parseCSV(data) {
    //alert(data);
    //replace UNIX new lines
    data = data.replace(/\r\n/g, "\n");
    //replace MAC new lines
    data = data.replace(/\r/g, "\n");
    //split into rows
    var rows = data.split("\n");
}

0
string s = Regex.Replace(source_string, "\n", "\r\n");

lub

string s = Regex.Replace(source_string, "\r\n", "\n");

w zależności od tego, którą drogą chcesz iść.

Mam nadzieję, że to pomoże.


0

Inną opcją jest utworzenie danego StringReaderciągu znaków. Na czytniku rób .ReadLine()w pętli. Następnie rozdzielamy linie, bez względu na to, jakie separatory (spójne lub niespójne) miały. Dzięki temu możesz kontynuować, jak chcesz; jedną z możliwości jest użycie StringBuilderi wywołanie .AppendLinego.

Zaletą jest to, że pozwalasz ramie decydować, co stanowi „podział linii”.


0

Jeśli chcesz zastąpić tylko nowe linie:

var input = @"sdfhlu \r\n sdkuidfs\r\ndfgdgfd";
var match = @"[\\ ]+";
var replaceWith = " ";
Console.WriteLine("input: " + input);
var x = Regex.Replace(input.Replace(@"\n", replaceWith).Replace(@"\r", replaceWith), match, replaceWith);
Console.WriteLine("output: " + x);

Jeśli chcesz zastąpić znaki nowej linii, tabulatory i białe znaki:

var input = @"sdfhlusdkuidfs\r\ndfgdgfd";
var match = @"[\\s]+";
var replaceWith = "";
Console.WriteLine("input: " + input);
var x = Regex.Replace(input, match, replaceWith);
Console.WriteLine("output: " + x);
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.