Emparejar saltos de línea - \ n o \ r \ n?


159

Mientras escribía esta respuesta , tenía que coincidir exclusivamente en los saltos de línea en lugar de usar s-flag ( dotall- el punto coincide con los saltos de línea).

Los sitios generalmente utilizados para probar expresiones regulares se comportan de manera diferente cuando se intenta hacer coincidir en \no \r\n.

Me di cuenta

  • Regex101 coincide con los saltos de línea solo en \n
    ( ejemplo : eliminar \ry coincide)

  • RegExr no coincide con los saltos de línea ni encendido \n ni encendido \r\n
    y no puedo encontrar algo que haga que coincida con un salto de línea, excepto por la mbandera y \s
    ( ejemplo )

  • Debuggex se comporta aún más diferente:
    en este ejemplo , solo coincide \r\n, mientras que
    aquí solo coincide \n, con los mismos indicadores y el mismo motor especificado

Soy plenamente consciente de la mbandera (multilínea, hace ^coincidir el inicio y $el final de una línea), pero a veces esto no es una opción. Lo mismo con \s, ya que coincide con las pestañas y los espacios también.

Mi idea de usar el carácter de línea nueva Unicode ( \u0085) no tuvo éxito, así que:

  1. ¿Hay alguna forma segura de integrar la coincidencia en un salto de línea (preferiblemente independientemente del lenguaje utilizado) en una expresión regular?
  2. ¿Por qué los sitios mencionados anteriormente se comportan de manera diferente (especialmente Debuggex, coincidiendo solo una \nvez y solo una vez \r\n)?

15
Puedes probar [\r\n]+, o algo así
Iłya Bursov el

3
Yo uso: \r?\npara que coincida con los dos \r\ny \nde terminación de línea secuencias. No funciona para la \rsintaxis antigua de Mac, pero esa es bastante rara en estos días.
ridgerunner

66
Hola, soy el fundador de debuggex. Esto parece un error (para depurar, no puedo hablar por los demás). He agregado un problema de alta prioridad que hace referencia a esta pregunta. Lo haremos lo antes posible: actualmente estamos centrando todos nuestros recursos (muy limitados) en el lanzamiento de otro producto.
Sergiu Toarca

2
@ridgerunner para agregar la sintaxis de Mac a eso, podría hacer (\ r? \ n | \ r), que es similar a la respuesta de Peter van der Wal a continuación, pero más compacta (10 caracteres frente a 12 caracteres).
Doktor J

Respuestas:


220

Voy a responder en la dirección opuesta.

2) Para obtener una explicación completa sobre \ry \ntengo que referirme a esta pregunta, que es mucho más completa de lo que publicaré aquí: ¿ Diferencia entre \ n y \ r?

En pocas palabras, Linux utiliza \npara una nueva línea, Windows \r\ny Macs antiguas \r. Por lo tanto, hay varias formas de escribir una nueva línea. Su segunda herramienta (RegExr), por ejemplo, coincide con el sencillo \r.

1) [\r\n]+como sugirió Ilya funcionará, pero también coincidirá con múltiples líneas nuevas consecutivas. (\r\n|\r|\n)Es más correcto.


Entonces, \r/ \ndependen del sistema operativo, eso es algo que uno puede saber (;)), pero ¿por qué los dos ejemplos de depuración coinciden una vez en \ r \ n y otra vez en \ n? Al menos no hay diferencia (en los ejemplos) visible para mí.
KeyNone

Lo más probable es que haya copiado uno de su editor de texto de Windows y el otro lo escribió directamente en el área de texto de depuración. Cada uno usaba diferentes saltos de línea.
OGHaza

1
De hecho, porque en su tercer ejemplo (los hombres mayores ...) hay una \r\nen el texto (si hace clic derecho y muestra la fuente, encontrará en {{Infobox XC Championships\r\n|Name =algún lugar). La segunda herramienta está escrita en Flash y, a medida que lees la página "acerca de", está un poco llena de errores con caracteres de nueva línea.
Peter van der Wal

1
(\r\n|\r|\n)se puede escribir de manera más simple como\r\n?
Asad Saeeduddin

2
@AsadSaeeduddin No, no puede. No coincidirá con el final de línea de Unix\n
Peter van der Wal

12

Tiene diferentes finales de línea en los textos de ejemplo en Debuggex. Lo que es especialmente interesante es que Debuggex parece haber identificado qué estilo de finalización de línea usó primero, y convierte todas las terminaciones de línea adicionales ingresadas a ese estilo.

Usé Notepad ++ para pegar texto de muestra en formato Unix y Windows en Debuggex, y lo que pegué primero es a lo que se aferró esa sesión de Debuggex.

Por lo tanto, debe lavar su texto a través de su editor de texto antes de pegarlo en Debuggex. Asegúrate de pegar el estilo que deseas. Debuggex tiene por defecto el estilo Unix (\ n).

Además, NEL (\ u0085) es algo completamente diferente: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)cubrirá Unix y Windows. Necesitará algo más complejo, por ejemplo (\r\n|\r|\n), si también quiere combinar Mac antiguo.


¡Un punto muy interesante sobre debuggex! Además, gracias por señalar \ u0085, ¡me engañé allí!
KeyNone


2

Esto solo se aplica a la pregunta 1.

Tengo una aplicación que se ejecuta en Windows y utiliza un cuadro de editor MFC de varias líneas.
El cuadro del editor espera saltos de línea CRLF, pero necesito analizar el texto ingresado
con algunas expresiones regulares realmente grandes / desagradables '.

No quería estresarme por esto mientras escribía la expresión regular, así
que terminé normalizando de un lado a otro entre el analizador y el editor para que
las expresiones regulares solo se usen \n. También atrapo operaciones de pegado y las convierto para las cajas.

Esto no lleva mucho tiempo.
Esto es lo que yo uso.

 boost::regex  CRLFCRtoLF (
     " \\r\\n | \\r(?!\\n) "
     , MODx);

 boost::regex  CRLFCRtoCRLF (
     " \\r\\n?+ | \\n "
     , MODx);


 // Convert (All style) linebreaks to linefeeds 
 // ---------------------------------------
 void ReplaceCRLFCRtoLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoLF, "\\n" );
 }

 // Convert linefeeds to linebreaks (Windows) 
 // ---------------------------------------
 void ReplaceCRLFCRtoCRLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoCRLF, "\\r\\n" );
 }

2

En Python:

# as Peter van der Wal's answer
re.split(r'\r\n|\r|\n', text, flags=re.M) 

o más riguroso:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.