Quiero eliminar cualquier línea nueva que ocurra entre dos tokens de rebajas para un encabezado. Por ejemplo:

### This is a long line that
I do not want broken up and I want it
on one line instead. ###

El encabezado puede tener varias líneas, por lo que se desconoce cuántas líneas nuevas hay en el texto.

Esto es lo que obtuve hasta ahora, pero obviamente no elimina todas las líneas nuevas:

s/^(#+\s+[^\n#]+)\n([^#]*#+)*)/$1 $2/g

Consulte también: https://regex101.com/r/xIHj0r/1

ACTUALIZACIÓN: Estoy haciendo esto en vim usando expresiones regulares similares a perl usando la etiqueta \ v de vim. Entonces estoy buscando una solución similar a Perl.

1
StevieD 24 ago. 2020 a las 03:28

2 respuestas

La mejor respuesta

Puede reemplazar las coincidencias de la siguiente expresión regular con un solo espacio.

/(?s)(?:^### |\G(?!(?:(?! ###$).)*^### ))[^\r\n]*(?:(?! ###)[^\r\n])*\K(?<! ###$)\r?\n/

¡Encienda su motor! 1

La complejidad de la expresión regular se debe principalmente a la necesidad de evitar eliminar nuevas líneas que no están entre los tokens de encabezado.

El motor de expresiones regulares de Perl realiza las siguientes operaciones.

(?s)            : assert single-line mode causing '.' to match
                  line terminators
(?:             : begin non-capture group
  ^###[ ]       : match '### ' at beginning of a line
  |             : or
  \G            : asserts position at the end of the previous match
                  or the start of the string for the first match
  (?!           : begin negative lookahead to assert that '### '
                  at the beginning of a line does not precede
                  ' ###' at the end of a line
    (?:         : begin non-capture group
      (?! ###$) : negative lookahead asserts current match is
                  not followed by ' ###' at the end of a line
      .         : match any character  
    )           : end non-capture group
    *           : execute non-capture group 0+ times
    ^###[ ]     : match '### ' at the beginning of a line
  )             : end negative lookahead
)               : end non-capture group       
[^\r\n]*        : match 0+ chars other than '\r' and '\n'
(?:             : begin non-capture group
  (?! ###)      : negative lookahead asserts current match is
                  not followed by ' ###' at the end of a line 
  [^\r\n]       : match 0+ chars other than '\r' and '\n' 
)               : end non-capture group
*               : execute non-capture group 0+ times
\K              : resets the starting point of the match and
                  discards any characters previously matched
(?<! ###)       : negative lookbehind asserts current match
                  is not preceded by ' ###'
\r?\n           : match '\n' optionally preceded by '\r'         

Esto utiliza la técnica token codicioso templado, que coincide con una serie de caracteres individuales que no comience una cadena no deseada. Se implementa con un grupo de no captura que se ejecuta un número variable de veces, una por cada carácter que coincide con éxito. El grupo de no captura comienza con un avance negativo que afirma que el siguiente carácter no es el primer carácter de la cadena no deseada. El primero de los dos usos de esta técnica aquí es el siguiente.

(?:         : begin non-capture group
  (?! ###$) : negative lookahead asserts current match is
              not followed by ' ###' at the end of a line
  .         : match any character  
)           : end non-capture group
*           : execute non-capture group 0+ times

Sin el largo avance negativo que sigue a \G el texto

Some text
before
### This is a long line that
I do not want broken up and I want it
on one line instead. ###
Some
text after

Se convertiría

Some text before ### This is a long line that I do not want broken up and I want it on one line instead. ###
Some
text after

Mientras

Some text
before
### This is a long line that I do not want broken up and I want it on one line instead. ###
Some
text after

Se quiere.

1 Tenga en cuenta que el cuadro "SUSTITUCIÓN" en el enlace contiene un solo espacio.

2
Cary Swoveland 24 ago. 2020 a las 15:13

Importación re

String = 'No quiero dividir y lo quiero \ no una línea en su lugar.'

Nueva_cadena = re.sub ('\ n', '', cadena)

Imprimir (nueva_cadena)

0
Anjaly Vijayan 24 ago. 2020 a las 00:51