Come sostituire diversi stili di Newline in PHP nel modo più intelligente?
Domanda
Ho un testo che potrebbe avere diversi stili di nuova linea. Voglio sostituire tutte le nuove linee ' r n', ' n', ' r' con la stessa nuova linea (in questo caso r n).
Qual è il modo più veloce per farlo? La mia soluzione attuale sembra questo che è molto succhiare:
$sNicetext = str_replace("\r\n",'%%%%somthing%%%%', $sNicetext);
$sNicetext = str_replace(array("\r","\n"),array("\r\n","\r\n"), $sNicetext);
$sNicetext = str_replace('%%%%somthing%%%%',"\r\n", $sNicetext);
Il problema è che non è possibile farlo con una sostituzione perché il r n verrà duplicato a r n r n.
Grazie per l'aiuto!
Soluzione
$string = preg_replace('~\R~u', "\r\n", $string);
Se non si desidera sostituire tutte le nuove linee Unicode ma solo quelle in stile CRLF, usa:
$string = preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $string);
\R
corrisponde a queste nuove linee, u
è un modificatore per trattare la stringa di input come UTF-8.
Dal PCRE DOCS:
Che cosa
\R
corrispondenzePer impostazione predefinita, la sequenza r in un modello corrisponde a qualsiasi sequenza di nuove linee Unicode, qualunque cosa sia stata selezionata come sequenza finale della linea. Se si specifica
--enable-bsr-anycrlf
L'impostazione predefinita viene modificato in modo che corrisponda solo a CR, LF o CRLF. Qualunque cosa sia selezionata quando è costruito PCRE può essere sovrascritto quando vengono chiamate le funzioni della libreria.
e
Sequenze di nuove linee
Al di fuori di una classe di caratteri, per impostazione predefinita, la sequenza di fuga corrisponde a qualsiasi sequenza di nuove linee Unicode. In modalità non UTF-8 R è equivalente a quanto segue:
(?>\r\n|\n|\x0b|\f|\r|\x85)
Questo è un esempio di un "gruppo atomico", i cui dettagli sono indicati di seguito. Questo particolare gruppo corrisponde alla sequenza a due caratteri CR seguita da LF o da uno dei singoli caratteri LF (linefeed, u+000a), VT (scheda verticale, u+000b), ff (formfeed, u+000c), CR (Ritorno a carrello, U+000D) o Nel (riga successiva, U+0085). La sequenza a due caratteri viene trattata come una singola unità che non può essere divisa.
Nella modalità UTF-8, vengono aggiunti due caratteri aggiuntivi i cui codepoint sono superiori a 255: LS (separatore di linee, u+2028) e PS (paragrafo separatore, u+2029). Il supporto della proprietà dei caratteri Unicode non è necessario affinché questi caratteri vengano riconosciuti.
È possibile limitare r per abbinare solo CR, LF o CRLF (anziché il set completo di termini della linea Unicode) impostando l'opzione pcre_bsr_anycrlf al momento della compilazione o quando il modello è abbinato. (BSR è un'abbrevazione per "Backslash R".) Questo può essere fatto il valore predefinito quando è costruito PCRE; In tal caso, l'altro comportamento può essere richiesto tramite l'opzione PCRE_BSR_UNICODE. È anche possibile specificare queste impostazioni avviando una stringa di pattern con una delle seguenti sequenze:
(*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence
Questi sovraccaricano il valore predefinito e le opzioni fornite a pcRe_compile () o pcre_compile2 (), ma possono essere sovrascritte dalle opzioni fornite a pcre_exec () o pcre_dfa_exec (). Si noti che queste impostazioni speciali, che non sono compatibili perl, sono riconosciute solo all'inizio di uno schema e che devono essere in maiuscolo. Se è presente più di uno di essi, viene utilizzato l'ultimo. Possono essere combinati con un cambio di Newline Convention; Ad esempio, un modello può iniziare con:
(*ANY)(*BSR_ANYCRLF)
Possono anche essere combinati con le sequenze speciali (*UTF8) o (*UCP). All'interno di una classe di caratteri, R è trattato come una sequenza di fuga non riconosciuta e quindi corrisponde alla lettera "R" per impostazione predefinita, ma provoca un errore se è impostato pCRE_EXTRA.
Altri suggerimenti
Per normalizzare le nuove linee che uso sempre:
$str = preg_replace('~\r\n?~', "\n", $str);
Sostituisce il vecchio Mac (\r
) e le finestre (\r\n
) NEWLINES con Equivalente UNIX (\n
).
Preferisco usare \n
Perché ci vuole solo un byte anziché due, ma puoi facilmente cambiarlo in \r\n
.
Che ne dite di
$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
Penso che il modo più intelligente/semplice per convertirsi in CRLF sia:
$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));
Convertire solo in LF:
$output = str_replace("\r", '', $input);
È molto più più facile delle espressioni regolari.