2013-05-22 9 views
5

Ist es möglich, nur Zeilenumbrüche zu wählen, denen keine regulären Ausdrücke vorausgehen? Ich bearbeite Untertitel für Studenten. Um die gedruckte Version toter Baum freundlich zu machen, versuche ich, alle Zeilenumbrüche, denen kein Punkt oder ein Fragezeichen vorausgeht, durch ein Leerzeichen zu ersetzen.Ersetzen Sie alle Zeilenumbrüche nicht durch einen Punkt mit einem regulären Ausdruck vorangestellt?

Option 1
wählen alle Zeilenumbrüche durch einen Punkt oder Fragezeichen regex nicht voran [a-z]\n für das funktioniert, aber dann ist es natürlich wählt den letzten Buchstaben des Wortes vor dem Zeilenumbruch. -> Ist es möglich, die letzten Buchstaben des Wortes vor dem Zeilenumbruch, um irgendwie zu speichern und einfügen und mit einem Leerzeichen einfügen zusammen reguläre Ausdrücke oder tut ich mit einem Skript für das schreiben habe (sagen php)

Option 2
Wählen Sie nur Zeilenumbrüche aus, denen ein Zeichen vorangestellt ist. Ich habe versucht, Lookbehind zu betrachten.

Beim Schreiben dieser Frage traf mich die Lösung. Um einen Zeilenumbruch vor einem Zeichen zu setzen, machen Sie (?<=[a-z])\n und ersetzen Sie ihn durch ein Leerzeichen.

Ich suchte Stapelüberlauf und konnte nicht wirklich finden, was ich suchte. Ich hoffe, ich werde niemanden beleidigen, indem ich die Frage und die Lösung zur gleichen Zeit stelle. Es könnte jemand anderem in der Zukunft helfen.

+7

Sie können Ihre eigene Frage beantworten – Blender

+2

Wenn Sie die Antwort auf Ihre eigene Frage, Post und es akzeptieren. Dies ist ein Standard, den Sie von SO erwarten. – Patashu

+0

Ich stimme @Blender zu. Du hast die richtigen Stücke. Denken Sie daran, dass ''. '' "Irgendein Zeichen" bedeutet, während '' .'' 'Punkt 'bedeutet und' 'R'' etwas sicherer als' '' ist. – mzedeler

Antwort

0

Die Syntax kann variieren, je nachdem, was Sie verwenden, um den Text zu ersetzen (Java, Perl, PHP, sed, vi usw.).

In Java könnten Sie dies versuchen:

str.replaceAll("([^\\.!?])\r?\n", "$1 ").replaceAll(" +", " "); 

In Perl:

perl -p -e 's/([^\.!?])\n/\1 /g; s/ +/ /g;' file.txt 

Sie können auch diese Antwort auf eine ähnliche Frage lesen:

How can I replace a newline (\n) using sed?

+0

können Sie ein Beispiel dafür mit PHP zeigen? – user1017063

+0

@wim hendrix Dies ist die Option 1. @Eric Citaire Sie müssen kein '.' innerhalb einer Zeichenklasse vermeiden. Ich glaube auch, dass die offizielle Empfehlung in Perl darin besteht, "$ 1" und nicht "\ 1" in der Ersetzungszeichenfolge zu verwenden. Es gibt ein Beispiel unter http://perldoc.perl.org/perlre.html#Quoting-metacharacters, aber ich habe nichts gefunden, was besagt, dass du '\ 1' nicht verwenden solltest. (In der Regex selbst würde ich jedoch '\ 1' verwenden.) –

0

Lassen Sie uns definieren eine Zeilenumbruch zuerst. In einigen Regex-Varianten, Java 8/PHP (PCRE), Ruby (Onigmo), können Sie eine Kurzschreibeklasse \R verwenden, die mit jedem Zeilenumbruchsstil übereinstimmt. In Java 8 regex reference, \R is defined als:

\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029] 

Nun, Sie wollen dieses Muster finden, wenn es nicht mit . char voraus. Sie müssen einen negativen Lookbehind, (?<!\.) verwenden. Es schlägt die Übereinstimmung fehl, sobald es eine . sofort auf der linken Seite des aktuellen Standorts findet.So, hier sind einige Beispiele dafür, wie der Zeilenumbruch entfernen nicht mit einem Punkt in einigen Sprachen voraus:

  • PHP (demo): preg_replace('~(\.\R+)|\R+~', '$1', $s)
  • Java 7 (demo): String rx_R = "(?:\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029])"; String res = s.replaceAll("(\\." + rx_R + ")|" + rx_R, "$1");
  • Rubin (demo): s.gsub(/(\.\R+)|\R+/, '\1')
  • C# (siehe demo): var rx_R = @"(?:\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029])"; var res = Regex.Replace(txt, [email protected]"(\.{rx_R})|{rx_R}", "$1");
  • Python (beide 2.x und 3.x) (demo): rx_R = r'(?:\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029])' und dann re.sub(r'(\.{0})|{0}'.format(rx_R), lambda x: x.group(1) if x.group(1) else '', s)
  • JavaScript: es hat keine Unterstützung für eine Lookbehind, so verwenden Sie eine ([^.]|^) Erfassung Gruppe und eine Rückreferenzierung ($1 es aus dem Ersatz-String zu verweisen), um die Zeichen anders als . vor einem Zeilenumbruch zu halten:

var s = "Line1\u000D\u000A Line2\u000B Line3\u000C Line4\u0085 Line5\u2028 Line6\u2029 Line7"; 
 
var rx = /([^.]|^)(?:\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029])/g; 
 
console.log(s.replace(rx, '$1'));

+0

Angenommen, ich teste einen Text, dessen EOL \ r \ n ist. In PHP verwende ich 'preg_replace ('~ (?

+0

@ScottChu Es ist aufgrund der Rückverfolgung und der Tatsache, dass '\ R' kein Muster fester Breite ist (Sie können es sehen, indem Sie auf das" abgerollte "' \ R' Zeichenklassenmuster sehen, es kann 1 oder 2 entsprechen Zeichen). Sobald das '\ r' gefunden ist, wird unmittelbar links davon nach' '' gesucht. Da es ein '.' gibt, ist' \ r' fehlgeschlagen und die Engine läuft weiter, um das '\ n' zu testen - und da es' \ r' vorangestellt ist (nicht ein '.'), ist dies' \ n' wird abgeglichen und durch ein Leerzeichen ersetzt. Sie müssen 'preg_replace ('~ (\. \ R +) | \ R + ~', '$ 1', $ s)' in PHP verwenden, siehe [** diese Demo **] (https://ideone.com/e7Ms5x). –

+0

@ScottChu Danke, dass Sie wissen lassen, ich könnte die Antwort verbessern. –

Verwandte Themen