Zeilenumbruch entfernen, ohne Absatz zu löschen

Mr. Brooks

Lt. Commander
Registriert
Aug. 2011
Beiträge
1.441
Hallo,

ich habe hier mehrere Bücher zu bearbeiten, bei denen jede Seite als einzelnes Bild vorliegt. Es handelt sich ausschließlich um Screenshots, die Texterkennung liegt ein paar Texts zufolge bei fast 100% Genauigkeit. Problem sind die Absätze. Ich verwende unter Ubuntu für die Texterkennung terreract-ocr in der Kommandozeile. Das Program gibt mir eine nette Textdatei aus, die Absätze werden richtig erkennt und durch eine Leerzeile voneinander getrennt. Das OCR-Programm speichert aber die Absätze nicht als einzelne Zeile ab, sondern hat da einen Zeilenumbruch eingefügt wo der Screenshot einen hatte. Für ein eBook im epub-Format ist es natürlich besser wenn es keine Zeilenumbrüche im Absatz gibt, damit die Zeilen im Reader richtig dargestellt werden.

Im Editor Kate kann ich einfach mit Suchen und Ersetzen nach

Code:
/n

und durch "nichts" ersetzen lassen - mit regulärem Ausdruck eingeschaltet.

Problem: Er erkennt auch die Leerzeile als solchen Zeilenumbruch. Diese soll ja aber gerade als Trennung zwischen den Absätzen erhalten bleiben.

Wie könnte man das lösen?

Mr. Brooks
 
\r = Carriage Return, Wagenrücklauf
\n = Line Feed, Zeilenvorschub

Ein Absatz ist gewöhnlich die Kombination aus beidem, also \r\n. Wenn ich deinen Beitrag richtig verstanden habe, dürfte das Suchen nach \r\n und Ersetzen durch nichts das Problem lösen. Ansonsten bitte ein Bild oder Beispieltext vom IST und vom SOLL.

€dit: Nach dem Beitrag von 0815burner kam mir noch ein Gedanke: Besteht der Absatz aus einer Leerzeile, ist es /r/n/n oder sogar \r\n\r\n. Am einfachsten ist es, den Text in einem Editor zu öffnen, der Steuerzeichen anzeigen kann. Kate kann das nur bedingt, wenn ich einer kurzen Googlesuche vertraue.

€dit2: Backslash natürlich, nicht Slash, argh.
 
Zuletzt bearbeitet:
Bei einer Leerzeile dazwischen müsste es doch /n/n sein.

Dann suche doch danach und ersetze dies dann durch ein einfaches /n.
 
Ich muss nach \n, nicht /n suchen.

Mit \n\n finde er die Leerzeile UND den letzten Zeilenumbruch des Absatzes, d.h. er würde dann alles zu einem Absatz zusammenpressen.

Nach so einem Editor suche ich auch, aber unter Linux scheint es sowas nicht zu geben. Dunkel erinnere ich mich, dass Notepad++ unter Windows sowas kann, ich finde das aber nicht mehr. Den hab ich über Wine installiert.
 
Backslashes statt Slashes, ja, sorry!

Für Notepad++:

5BuaKYv.png


Und sicher gibt es so was auch für Linux. Die beiden Klassiker vim und emacs können das zum Beispiel, sind aber nicht sonderlich einsteigerfreundlich in der Bedienung. Ein paar Möglichkeiten für Ubuntu: https://ubuntuforums.org/showthread.php?t=868855

Unabhängig davon verstehe ich noch immer nicht, was du als Absatz und was als Leerzeile definierst. Deswegen noch einmal die Bitte nach einem Beispieltext oder -screenshot mit dem IST und einem mit dem SOLL.
 
Das ist ein gescanntes Buch, also ein urheberrechtlich geschütztes Werk. Würde ich jetzt den Text hier posten wäre das eine Urheberrechtsverletzung. Daher hier mal ein Text aus der Wikipedia:

Ein regulärer Ausdruck (englisch regular expression, Abkürzung RegExp oder Regex) ist in der theoretischen Informatik eine Zeichenkette, die der Beschreibung von Mengen von Zeichenketten mit Hilfe bestimmter syntaktischer Regeln dient. Reguläre Ausdrücke finden vor allem in der Softwareentwicklung Verwendung. Neben Implementierungen in vielen Programmiersprachen verarbeiten auch viele Texteditoren reguläre Ausdrücke in der Funktion „Suchen und Ersetzen“. Ein einfacher Anwendungsfall von regulären Ausdrücken sind Wildcards.

Reguläre Ausdrücke können als Filterkriterien in der Textsuche verwendet werden, indem der Text mit dem Muster des regulären Ausdrucks abgeglichen wird. Dieser Vorgang wird auch Pattern Matching genannt. So ist es beispielsweise möglich, alle Wörter aus einer Wortliste herauszusuchen, die mit S beginnen und auf D enden, ohne die dazwischen liegenden Buchstaben oder deren Anzahl explizit vorgeben zu müssen.

Der Begriff des regulären Ausdrucks geht im Wesentlichen auf den Mathematiker Stephen Kleene zurück. Dieser benutzte eine fast identische Bezeichnung, die er reguläre Mengen nannte.

Was ein Absatz ist sollte denke ich klar sein, auch was eine Leerzeile ist. Dieser Text hat 3 Absätze und 2 Leerzeilen. In meinem Beispiel wird sowohl das Ende jeder Zeile als auch die Leerzeile mit einem "\n" angezeigt.

Ich hatte noch die Idee, dass man nach "\n" am Zeilenanfang suchen lässt, also sowas wie

Code:
^\n

hat aber nicht funktioniert. Sowas wie

Code:
^[A-Z]

geht aber.
 
Da bin ich auch auf die Backslashes reingefallen:rolleyes:

Unter Linux kann das Suchen und Ersetzen gedit. Notepad++ vermisse ich dort aber auch. Gedit ist mir bisher noch der meistzusagendste Ersatz. Unter Xubuntu ist bei gedit das Bedienfeld rechts oben neben dem X.

Du suchst, wie ich oben versucht habe richtig darzustellen, nach \n\n und ersetzt es mit einem Zeilenumbruch bzw. carriage return. Also \r oder \n. Dann sollte es doch passen.

Edit: gedit macht das Ersetzen logischerweise auch, wenn die Steuerzeichen nicht angezeigt werden.

Edit2: Nochmal gelesen und neu verstanden:p
Du willst also die einfachen Zeilenumbrüche weghaben. Dann suche nach \n+Leerzeichen und entferne das durch ein Leerzeichen. Bei einem "richtigen" Absatz sollte das \n\n doch direkt aufeinander folgen. und würde dann nicht gefunden und geändert.
Dachte du wolltest die Leerzeile zwischen den Abschnitten weghaben, den Absatz aber als solchen behalten.

Edit3: meine Lösung geht nicht und irgendwie finde ich auch nichts passendes. habe aber das hier gefunden:
http://www.ooowiki.de/SuchenUndErsetzen.html#Sonderzeichen
 
Zuletzt bearbeitet:
Richtig. Es gibt kein \n\n in dem Dokument, außer ein \n am Ende einer Zeile und ein weiteres \n in der Leerzeile, aber kein \n\n das direkt die Leerzeile darstellt.

Evtl. hab ich eine Lösung gefunden, mal sehen ob die mich weiter bringt. Man könnte in einem ersten Schritt \n\n durch \r\n (dem Windowszeilenumbruch) ersetzen. Oder man ersetzt \n\n durch \n\t. Das löscht zwar die Leerzeile, rückt das 1. Wort des neues Absatzes aber ein - das ist sogar die Darstellung wie sie im Originalbild gewählt wurde.

Mal sehen ob mir einer der Varianten bei der Weiterbearbeitung hilft.
 
Mr. Brooks schrieb:
Was ein Absatz ist sollte denke ich klar sein, auch was eine Leerzeile ist. Dieser Text hat 3 Absätze und 2 Leerzeilen.

Jo, das reicht schon mal als Beispiel für das IST. Wenn ich dich richtig verstanden habe, möchtest du den Zeilenumbruch beibehalten, die Leerzeile aber entfernt haben, sodaß Absätze ohne Leerzeile entstehen. Richtig? Der fertige Text soll also so aussehen:

Ein regulärer Ausdruck (englisch regular expression, Abkürzung RegExp oder Regex) ist in der theoretischen Informatik eine Zeichenkette, die der Beschreibung von Mengen von Zeichenketten mit Hilfe bestimmter syntaktischer Regeln dient. Reguläre Ausdrücke finden vor allem in der Softwareentwicklung Verwendung. Neben Implementierungen in vielen Programmiersprachen verarbeiten auch viele Texteditoren reguläre Ausdrücke in der Funktion „Suchen und Ersetzen“. Ein einfacher Anwendungsfall von regulären Ausdrücken sind Wildcards.
Reguläre Ausdrücke können als Filterkriterien in der Textsuche verwendet werden, indem der Text mit dem Muster des regulären Ausdrucks abgeglichen wird. Dieser Vorgang wird auch Pattern Matching genannt. So ist es beispielsweise möglich, alle Wörter aus einer Wortliste herauszusuchen, die mit S beginnen und auf D enden, ohne die dazwischen liegenden Buchstaben oder deren Anzahl explizit vorgeben zu müssen.
Der Begriff des regulären Ausdrucks geht im Wesentlichen auf den Mathematiker Stephen Kleene zurück. Dieser benutzte eine fast identische Bezeichnung, die er reguläre Mengen nannte.

Das erreicht man durch das Ersetzen von \r\n\r\n mit \r\n.

lRpJyal.png


Wenn der Text nicht so aussehen soll, bitte wieder ein Beispiel mit dem Regex-Text aus der Wiki.
 
Nein. Ich will den Zeilenumbruch am Ende der Zeilen löschen, aber die Leerzeile zwischen den Absätzen lassen. Es soll also zwischen allen Absätzen eine Leerzeile bleiben.

Im o.g. Beispiel soll also der Zeilenumbruch nach "der", "Hilfe", "Softwareentwicklung", "Texteditoren", "regulären" und "Wildcards." gelöscht werden. Die darauf folgende Leerzeile aber bestehen bleiben. Das ganze dann weiter für den 2. Absatz.

Das erreicht man durch das Ersetzen von \r\n\r\n mit \r\n.

Und genau das geht ja nicht. Es gibt kein \r\n oder \r\n\r\n in dem Dokument. Die Leerzeile ist einfach \n

Ich hab es jetzt geschafft aus dem Wiki-Text genau das zu machen was mir tesseract-ocr ausgibt und angehängt.
 

Anhänge

Wir scheinen unterschiedliche Definitionen von Zeilenumbruch zu verwenden. Die Zeilenumbrüche nach „der“, „Hilfe“, „Softwareentwicklung“, „Texteditoren“, „regulären“ und „Wildcards“ sind sozusagen weiche Zeilenumbrüche, die von der Auflösung des Browserfensters bzw. darstellenden Gerätes abhängen und dynamisch erzeugt werden. In einem Vollbild-Browserfenster auf einem FullHD-Bildschirm habe ich im ersten Absatz des Beispieltexts nur einen weichen Zeilenumbruch nach „syntaktischer“ und „Funktion“. Da an diesen Stellen aber kein Steuerzeichen steht, sondern der Browser einfach in die nächste Zeile hüpft, sobald der Text nicht mehr in die aktuelle passen würde, gibt es auch nichts, was man ersetzen kann.

Damit habe ich jetzt auch endlich verstanden, was du die ganze Zeit meinst. Ein Screenshot oder zwei Beispieltexte hätten das zwar von Anfang an klargemacht, aber egal. Das Problem ist, daß du jetzt harte Zeilenumbrüche an Stellen hast, an denen vorher nur dynamische waren.

7PVqE7C.png


Was ich trotzdem noch nicht verstehe, ist

Mr. Brooks schrieb:
Und genau das geht ja nicht. Es gibt kein \r\n oder \r\n\r\n in dem Dokument. Die Leerzeile ist einfach \n

Es kann kein einfaches \n sein. Das springt vertikal nur eine Zeile weiter nach unten, ohne horizontal wieder an den Zeilenanfang ganz links zu gehen. Würde man das in einem fortlaufenden Text machen, bekäme man so etwas heraus:

Code:
Lorem ipsum dolor sit amet, consetetur
                                      sadipscing elitr, sed diam nonumy eirmod
                                                                              tempor invidunt ut labore et dolore magna aliquyam erat, sed
                                                                                                                                          diam voluptua.



Die angehängte .txt ist ein wenig seltsam. Notepad++ stellt sie so dar:

56mqYWp.png


Der stinknomale Windows-Texteditor dagegen so:

s06nOsw.png


Beide interpretieren also das Aussehen von \n ohne drauffolgendes \r anders. Bringt uns aber nicht weiter.

Wenn ich in der angehängten beispiel.txt nach \n\n suche, erhalte ich in Notepad++ dafür zwei Treffer:

8rvUDpQ.png


Die sollen ja aber gerade nicht getroffen werden. Es soll sich nur auf einzelne Vorkommen von \n beziehen, auf die kein zweites \n folgt. Soweit ich das einschätzen kann, müßte man dafür eine Regex basteln, die sagt:

„Finde alle \n, auf die KEIN Backslash folgt“

Weil das über meine Regexkenntnisse hinausgeht, habe ich mir einen Umweg überlegt. Das Problem ist, daß in \n\n auch \n steckt. Das muß man irgendwie wegbekommen. Also sucht man nach \n\n und ersetzt es mit irgendeiner exotischen Zeichenkombination wie @|@, die sonst nirgends im Dokument vorkommt und mit der man später die Kombination Absatz + Leerzeile wiederherstellen kann.

6buCDv0.png


Damit bleiben nur noch einzelne \n übrig, die man durch ein Leerzeichen (nicht nichts!) ersetzen kann. Anschließend ersetzt man @|@ wieder durch \n\n und stellt damit die Absätze + Leerzeile wieder her.

Voilà, fertig ist die bereinigte .txt. War doch gar nicht so schwierig, sobald das Problem erst mal erkannt war. :D
 
Gar lusitg, das :)

Wenn ich \n\n in \n ersetze und im 2. Schritt alle \n durch Leerzeichen gibt das einen Schuss ins Knie.

DeusoftheWired hält da schon den Finger in die Wunde. Zeilen gibt es nicht, effektiv nur Absätze. Alles zwischen 2 \n (bzw. 2 \r\n) ist so ein Absatz der von Editoren auf Wunsch (order in Word unvermeidlich) am Fensterrand (Blattrand) umbrochen wird und scheinbar Zeilen liefert.

Meine Lösung, die ich oft nutzen muss, ist \n\n in etwas Einzigartiges umwandeln (### etwa , was wohl nie im Text auftaucht), dann die \n ins Leerzeichen und die ### wieder in \n\n um die Trenn-»Zeile«, den Trenn-Absatz, zu erzeugen.

CN8
 
Die Zeilenumbrüche nach „der“, „Hilfe“, „Softwareentwicklung“, „Texteditoren“, „regulären“ und „Wildcards“ sind sozusagen weiche Zeilenumbrüche, die von der Auflösung des Browserfensters bzw. darstellenden Gerätes abhängen und dynamisch erzeugt werden.

Nein sind sie nicht. ES wurde IMMER an genau dieser Stelle die Zeile beendet unabhängig davon wie weit ich das auseinander gezogen habe.
Es kann kein einfaches \n sein.

War es aber. Ich hab es ja in Kate gesucht und da habe ich mit allen anderen als \n nichts gfeunden. Mit \n\n habe ich was gefunden, das war dann aber das eine \n am Ende der letzte Zeile des Absatzes und das 2. \n in der Leerzeile.

Wie das zustande kommt weiß ich nicht. Auch nicht ob das korrekt ist. Das ist was mit tesseract-or ausgegeben hat. Wurde auch in allen Editoren korrekt dargestellt.

Deine Idee mit dem exotischen Zeichen war aber dennoch gut, das hat jetzt in einem ersten Test funktioniert. Mal sehen ob ich das auch auf alle Seiten so anwenden kann.

EDIT
Womöglich war mein selbst erstelltes Bsp. mit dem Wiki-Text nicht 1:1 vergleichbar mit dem Text des tesseract ausgegeben hat.
 
Mr. Brooks schrieb:
Ich hab es ja in Kate gesucht und da habe ich mit allen anderen als \n nichts gfeunden. Mit \n\n habe ich was gefunden, das war dann aber das eine \n am Ende der letzte Zeile des Absatzes und das 2. \n in der Leerzeile.

Wie gesagt, mit Notepad++ habe ich für \n\n in deiner beispiel.txt zwei Treffer bei der Suche gehabt. Das sind die Absätze mit Leerzeile. Ich hab mit ein wenig Sucherei mittlerweile auch den Grund für die Verwirrung gefunden und selbst noch etwas dazugelernt. Die Kombination aus \r und \n ist eine Windowseigenart. Unixe brauchen nur ein \n. Tesseract hält sich hier also den Unixstandard. https://de.wikipedia.org/wiki/Zeilenumbruch#Programmierung:_Codierung_des_Umbruchs
Hübsch wäre es, wenn tesseract einen Parameter für die Ausgabe eines Textes hätte, der auf Windowssystemen gelesen werden soll. Hab in den manpages dazu nichts gefunden.

Mr. Brooks schrieb:
Deine Idee mit dem exotischen Zeichen war aber dennoch gut, das hat jetzt in einem ersten Test funktioniert. Mal sehen ob ich das auch auf alle Seiten so anwenden kann.

Gerne doch. Und hoffentlich klappt’s auch auf den restlichen Seiten!
 
Zurück
Oben