¿Cómo reemplazar diferentes estilos de nueva línea en PHP de la manera más inteligente?
Pregunta
Tengo un texto que podría tener diferentes estilos de nueva línea. Quiero reemplazar todas las nuevas líneas ' r n', ' n', ' r' con la misma nueva línea (en este caso r n).
¿Cuál es la forma más rápida de hacer esto? Mi solución actual se ve así, que es muy sucky:
$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);
El problema es que no puede hacer esto con un reemplazo porque el r n se duplicará a r n r n.
¡Gracias por tu ayuda!
Solución
$string = preg_replace('~\R~u', "\r\n", $string);
Si no desea reemplazar todas las nuevas líneas de Unicode pero solo las de estilo CRLF, use:
$string = preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $string);
\R
coincide con estas nuevas líneas, u
es un modificador para tratar la cadena de entrada como UTF-8.
Desde el Documentos de pcre:
Qué
\R
partidosPor defecto, la secuencia R en un patrón coincide con cualquier secuencia de Newline Unicode, lo que se haya seleccionado como la secuencia de finalización de la línea. Si especifica
--enable-bsr-anycrlf
El valor predeterminado se cambia para que r coincida solo con Cr, LF o CRLF. Lo que se seleccione cuando se construye PCRE se puede anular cuando se llaman a las funciones de la biblioteca.
y
Secuencias de nueva línea
Fuera de una clase de caracteres, por defecto, la secuencia de escape r coincide con cualquier secuencia de Newline unicode. En el modo no UTF-8 r es equivalente al siguiente:
(?>\r\n|\n|\x0b|\f|\r|\x85)
Este es un ejemplo de un "grupo atómico", cuyos detalles se dan a continuación. Este grupo en particular coincide con la secuencia de dos caracteres CR seguida de LF, o uno de los caracteres individuales LF (Linefeed, U+000a), VT (Tab vertical, U+000b), FF (FormFeed, U+000c), CR (retorno del carro, u+000d) o NEL (siguiente línea, u+0085). La secuencia de dos caracteres se trata como una sola unidad que no se puede dividir.
En el modo UTF-8, se agregan dos caracteres adicionales cuyos puntos de código son mayores de 255: LS (separador de línea, U+2028) y PS (separador de párrafo, U+2029). No se necesita soporte de propiedad de caracteres Unicode para que estos personajes sean reconocidos.
Es posible restringir r para que coincidan solo con Cr, LF o CRLF (en lugar del conjunto completo de terminaciones de línea Unicode) configurando la opción PCRE_BSR_AYCRLF en el momento de la compilación o cuando el patrón coincide. (BSR es una abrevación para "Back -staglash R".) Esto se puede hacer de manera predeterminada cuando se construye PCRE; Si este es el caso, el otro comportamiento se puede solicitar a través de la opción PCRE_BSR_UNICODE. También es posible especificar estas configuraciones iniciando una cadena de patrón con una de las siguientes secuencias:
(*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence
Estos anulan el valor predeterminado y las opciones dadas a pcre_compile () o pcre_compile2 (), pero pueden ser anuladas por las opciones dadas a pcre_exec () o pcre_dfa_exec (). Tenga en cuenta que estas configuraciones especiales, que no son compatibles con Perl, se reconocen solo al comienzo de un patrón, y que deben estar en el primer caso. Si más de uno de ellos está presente, se usa el último. Se pueden combinar con un cambio de convención de nueva línea; Por ejemplo, un patrón puede comenzar con:
(*ANY)(*BSR_ANYCRLF)
También se pueden combinar con las secuencias especiales (*UTF8) o (*UCP). Dentro de una clase de caracteres, R se trata como una secuencia de escape no reconocida, por lo que coincide con la letra "R" de forma predeterminada, pero causa un error si se establece PCRE_EXTRA.
Otros consejos
Para normalizar las nuevas líneas siempre uso:
$str = preg_replace('~\r\n?~', "\n", $str);
Reemplaza la vieja mac (\r
) y las ventanas (\r\n
) nuevas líneas con el equivalente de UNIX (\n
).
Prefiero usar \n
Porque solo se necesita un byte en lugar de dos, pero puedes cambiarlo fácilmente a \r\n
.
Qué tal si
$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
Creo que la forma más inteligente/más simple de convertir a CRLF es:
$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));
para convertir a LF solamente:
$output = str_replace("\r", '', $input);
Es mucho más fácil que las expresiones regulares.