2013-05-22 13 views
5

È possibile selezionare solo interruzioni di riga non precedute da un punto utilizzando le espressioni regolari? Sto modificando i file dei sottotitoli per gli studenti. Per rendere la versione stampata dead tree friendly, sto cercando di sostituire tutte le interruzioni di riga non precedute da un punto o punto interrogativo con uno spazio.sostituire tutte le interruzioni di riga non precedono di un punto con un'espressione regolare?

opzione 1
selezionare tutta la linea non rompe preceduta da un periodo o interrogativo regex [a-z]\n lavora per questo, ma poi, naturalmente, seleziona l'ultima lettera della parola prima della interruzione di riga. -> E 'possibile salvare in qualche modo e inserire l'ultima lettera della parola prima che l'interruzione di riga e inserire che, insieme con uno spazio utilizzando le espressioni regolari o devo scrivere uno script per questo (ad esempio PHP)

opzione 2
Selezionare solo interruzioni di riga precedute da un carattere. Ho provato a guardare dietro le quinte.

Mentre scrivevo questa domanda la soluzione mi ha colpito. Per selezionare un'interruzione di riga precedere da un carattere fare (?<=[a-z])\n e quindi sostituirlo con uno spazio.

Ho cercato overflow dello stack e non riuscivo a trovare veramente quello che stavo cercando. Spero di non offendere nessuno pubblicando la domanda e la soluzione allo stesso tempo. Potrebbe aiutare qualcun altro in futuro.

+7

si può rispondere alla tua domanda – Blender

+2

Se avete la risposta alla tua stessa domanda, posta e lo accetto. Questa è una cosa standard che dovresti fare su SO. – Patashu

+0

Sono d'accordo con @Blender. Hai i pezzi giusti. Ricorda che '' .'' significa "qualsiasi carattere", mentre '' \ .'' significa "punto" e '' \ R'' è un po 'più sicuro di '' \ n''. – mzedeler

risposta

0

La sintassi può variare a seconda di ciò che si sta utilizzando per sostituire il testo (Java, Perl, PHP, sed, vi, ecc.).

In Java si potrebbe provare questo:

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

in Perl:

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

si può anche leggere questa risposta a una domanda simile:

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

+0

puoi mostrare un esempio di questo usando php? – user1017063

+0

@wim hendrix Questa è l'opzione 1. @Eric Citaire Non è necessario sfuggire a un '.' all'interno di una classe di caratteri. Inoltre, credo che la raccomandazione ufficiale in Perl sia/fosse di usare '$ 1' e non' \ 1' nella stringa di sostituzione. C'è un esempio su http://perldoc.perl.org/perlre.html#Quoting-metacharacters, ma non sono riuscito a trovare nulla che dice che non si dovrebbe usare '\ 1'. (Nella regex stessa, comunque, userei ancora '\ 1'.) –

0

Definiamo una interruzione di riga prima. In alcuni tipi di espressioni regex, Java 8/PHP (PCRE), Ruby (Onigmo), è possibile utilizzare una classe di caratteri stenografici \R corrispondente a qualsiasi stile di interruzione di riga. In Java 8 regex reference, \R is defined come:

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

Ora, si desidera trovare questo schema, se non è preceduto da . char. È necessario utilizzare uno sguardo negativo dietro, (?<!\.). Non riesce la corrispondenza una volta trovato uno . immediatamente a sinistra della posizione corrente.Quindi, ecco alcuni esempi di come rimuovere l'interruzione di riga non è preceduta con un punto in alcune lingue:

  • 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");
  • Rubino (demo): s.gsub(/(\.\R+)|\R+/, '\1')
  • C# (vedi 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 (sia 2.xe 3.x) (demo): rx_R = r'(?:\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029])' e poi re.sub(r'(\.{0})|{0}'.format(rx_R), lambda x: x.group(1) if x.group(1) else '', s)
  • JavaScript: non ha il supporto per un lookbehind, quindi, utilizzare un gruppo di cattura ([^.]|^) e backreference ($1 di riferimento dalla stringa di sostituzione) per mantenere il char diverso . prima di un'interruzione di linea:

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

Dire che testare un testo il cui EOL è \ r \ n. In PHP, utilizzo 'preg_replace ('~ (?

+0

@ScottChu È dovuto al backtracking e al fatto che '\ R' non è un pattern a larghezza fissa (puoi vederlo guardando il pattern di classe di carattere" srotolato "' \ R', potrebbe corrispondere a 1 o 2 caratteri). Una volta trovato '\ r', viene cercato un' .' immediatamente a sinistra di esso. Poiché c'è un '.',' \ r' non è riuscito e il motore va avanti per testare '\ n' - e poiché è preceduto da' \ r' (non un '.'), questo' \ n' è abbinato e sostituito con uno spazio. Devi utilizzare 'preg_replace ('~ (\. \ R +) | \ R + ~', '$ 1', $ s)' in PHP, vedi [** questa demo **] (https://ideone.com/e7Ms5x). –

+0

@ScottChu Grazie per avermelo detto, ho potuto migliorare la risposta. –

Problemi correlati