¿Qué tan audaz es esta publicación?

13

Preámbulo

En el descuento de Stack Exchange, usamos ** para poner en negrita el texto. Por ejemplo, esta rebaja:

The **quick brown fox jumps over the lazy** dog.

Representa como:

El rápido zorro marrón salta sobre el perro perezoso .

Por supuesto, también usamos ** para cerrar la audacia. Entonces, menos de la respuesta será audaz. Por ejemplo:

The **quick** brown fox jumps over the **lazy** dog.

Representa como:

El rápido zorro marrón salta sobre el perro perezoso .

Sin embargo, si la negrita no está cerrada, se muestra como no negrita :

The **quick brown fox jumps over the lazy dog.

Representa como:

El ** zorro marrón rápido salta sobre el perro perezoso.

Si el texto tiene una barra invertida simple \, la negrita no tiene efecto:

The \**quick brown fox jumps over the lazy dog.**

Representa como:

El ** zorro marrón rápido salta sobre el perro perezoso. **

El espacio en blanco al final da como resultado texto sin negrita (tenga en cuenta que el espacio en blanco después del marrón es una sola pestaña):

The** quick** brown fox jumps over the lazy dog.**

Representa como:

El ** zorro marrón ** rápido ** salta sobre el perro perezoso. **

También podemos usar __ para negrita, pero tenga en cuenta que solo uno puede estar activo a la vez. Aquí hay un ejemplo más complicado:

The __quick**__ brown **fox__ jumps** over__ the__ lazy **dog.

Representa como:

La rápida ** marrón fox__ salta over__ the__ perro ** perezoso.

La pregunta:

Usted puede escribir un programa o función, texto ASCII administrada en forma de Stringargumento o la entrada estándar, donde los únicos caracteres especiales son **, __, \(para escapar) y con espacios en blanco, determinar el número de caracteres en negrita existen. Este valor debe imprimirse en STDOUT o devolverse desde su función. No necesita soportar cadenas muy largas; Se garantiza que la longitud de la cadena no será mayor que 30K, que es el límite para una publicación de Stack Exchange.

Letra pequeña:

  • ¿Puedo lanzar una excepción / otro error para un caso y regresar normalmente para el otro?
    • No. Debe ser un valor de retorno claro, inequívoco y sin errores para ambos casos. La salida STDERR será ignorada.
  • ¿Los espacios entre palabras se consideran negrita?
    • Si. **quick brown**tiene 11 caracteres en negrita.
  • ¿Debería contarse el \in \**, si está en negrita?
    • No. Se representa como **, por lo que si debe estar en negrita, solo tendrá 2 caracteres.
  • Sea completamente claro: ¿qué quiere decir con cuántos personajes?
    • Total de caracteres que se pondrían en negrita Esto significa que **está sin fundir si se transforma el texto, sino que se hace si no lo hace.
    • Tenga en cuenta que es posible hacer **en negrita de varias maneras, por ejemplo, **\****-> ** .
    • No considere la posibilidad de que parte del texto pueda convertirse en cursiva. La única regla de rebajas a considerar es ** = negrita *.
  • En Stack Exchange, HTML Bold también funciona. es decir, <b> </b>
    • Si, estoy enterado. No considere este caso, este es un texto normal.
  • ¿Qué pasa con las entradas HTML? por ejemplo &lt;-><
    • Estos también deben considerarse como texto normal, no hay conversión de entidad HTML.
  • ¡He pensado en un ejemplo que no cubriste arriba!
    • Las reglas funcionan exactamente como si el texto se publicara en Stack Exchange, en una respuesta (no en un comentario), excepto que los bloques de código no se consideran caracteres especiales . Tanto el tipo de cuatro espacios como el tipo de retroceso. Si no está seguro de cómo se debe representar el texto, simplemente tírelo en un cuadro de respuesta en alguna parte como prueba, esas son las reglas que debe seguir.

Ejemplos:

Entrada:

The **quick brown fox jumps over the lazy** dog.

Salida:

35

Entrada:

The **quick brown fox jumps over the lazy dog.

Salida:

0

Entrada:

The __quick**__ brown **fox__ jumps** over__ the__ lazy **dog.

Salida:

18

Entrada:

The __quick\____ brown fox **jumps over\** the** lazy \**dog.

Salida:

23

Entrada:

The****quick brown fox****jumps over **the****lazy** dog.

Salida:

11

Las lagunas estándar están prohibidas.

durron597
fuente
¿Es 18correcto para el tercer caso de prueba?
Beta Decay
@BetaDecay Son 7 + 11. ¿Qué crees que debería ser?
durron597
He estado recibiendo 28 ... Revisaré mi programa
Beta Decay
@BetaDecay **fox__ jumps**termina ese negrita particular.
durron597
1
La pregunta parece sugerir que \**o \__son secuencias de escape de tres caracteres, pero en StackExchange solo hay secuencias de escape de dos caracteres \*o \_. Entonces \***a**produce un asterisco seguido de un negrita a. También hay otro escape, \\ . ¿Deberíamos manejar eso?
feersum

Respuestas:

5

rs , 107 bytes

\t/ 
(?<!\\)((\*|_){2})((?=\S)(?!\2)(\\\2|.)*?)?(?<=\S)\1/(\n)^^((^^\3))\3
\\(\*|_)/\t
[^\t\n]/
\n/_
\t_?/
(_*)/(^^\1)

Demostración en vivo y casos de prueba.

Esto es una locura ... cosa.

El último caso de prueba aún no funciona. WIP ...

Explicación

\t/ 

Reemplace las pestañas con espacios. Tienen el mismo número de caracteres, y las pestañas se usan más adelante como un carácter especial.

(?<!\\)((\*|_){2})((?=\S)(?!\2)(\\\2|.)*?)?(?<=\S)\1/(\n)^^((^^\3))\3

Reemplace cualquier texto de longitud Nque debe estar en negrita con Nnuevas líneas seguidas del texto original.

\\(\*|_)/\t

Reemplace cualquier aparición de un delimitador precedido inmediatamente por una barra diagonal con una pestaña. Esto es para asegurarse de que las entradas como **a\***tienen un recuento de caracteres de 2 en lugar de 3.

[^\t\n]/

Elimine cualquier carácter que no sea una pestaña o una nueva línea.

\n/_

Reemplace todas las líneas nuevas con guiones bajos.

\t_?/

Elimine las pestañas (que representan delimitadores escapados), junto con los guiones bajos que puedan seguir. Esto está relacionado con el problema anterior de recuentos de caracteres con delimitadores finales escapados.

(_*)/(^^\1)

Reemplace la secuencia de subrayado con su longitud. Este es el recuento de personajes.

kirbyfan64sos
fuente
**a****b**salidas 2, debería ser 6. Ver: a **** b
durron597
1
@ durron597 Estoy un poco confundido sobre cómo se supone que debe funcionar. ¿Podría agregar una explicación?
kirbyfan64sos
Como dije, solo juega con él en un panel de respuesta. **** siempre es solo asteriscos, que pueden estar dentro de una negrita o no dentro de una negrita según el otro texto.
durron597
Entonces, @ kirbyfan64sos, ¿qué tan audaz es la publicación?
mbomb007
2

Python: 133 caracteres

import re
f=lambda s:sum(len(x[0])-4for x in re.findall(r'(([_*])\2\S.*?\2\2+)',re.sub(r'([_*])\1\1\1','xxxx',re.sub(r'\\.','x',s))))

Esto debería funcionar de manera idéntica en Python 2 y 3. La función fdevuelve el número de caracteres en negrita que estarán en la cadena que se pasa cuando formatea el sistema de rebajas de Stack Overflow.

Creo que tengo la mayoría de los casos de esquina correctos (incluidos todos los mencionados en los comentarios hasta ahora), pero aún no es del todo perfecto. No entiendo por qué x***x**no se muestra *xen negrita (como lo ***x**hace), por lo que mi código obtendrá al menos algunas entradas incorrectas.

El código tiene cuatro pasos principales. El primero hace un reemplazo de expresiones regulares de cualquier barra invertida seguido de cualquier carácter con un carácter 'x'. El segundo paso reemplaza cualquier secuencia de cuatro asteriscos o guiones bajos con cuatro caracteres 'x'. El tercer paso usa una expresión regularfindall para encontrar todos los bloques que estarán en cursiva. El paso final es una expresión generadora dentro de una sumllamada, que suma las longitudes de esos bloques, restando 4 caracteres de cada uno, ya que no queremos incluir los delimitadores en nuestro recuento.

Aquí hay algunos resultados de prueba:

>>> f('The **quick brown fox jumps over the lazy** dog.')
35
>>> f('The **quick brown fox jumps over the lazy dog.')
0
>>> f('The \**quick brown fox jumps over the lazy dog.**')
0
>>> f('The** quick** brown fox jumps over the lazy dog.**')
0
>>> f('The __quick\____ brown fox **jumps over\** the** lazy \**dog.')
23
>>> f('The****quick brown fox****jumps over **the****lazy** dog.')
11
>>> f('\***a**')
1
>>> f('x***x**') # this one doesn't match the Stack Overflow input box
2
Blckknght
fuente
No tengo idea de por qué x***x**no funciona en el cuadro de entrada. Extraño
durron597
1

JavaScript ES6, 91 bytes

s=>(o=0,s.replace(/\\(.)\1/g,'..').replace(/(\*\*|__)(?=\S)(.*?\S)\1/g,l=>o+=l.length-4),o)

Trata todos los escapes de antemano, luego usa una expresión regular. Gran potencial de golf.

Explicación

s=>( // Function with argument s
  o=0, // Set var "o" to 0
  s.replace( // Replace...
    /\\(.)\1/g,  // Matches \ followed by two the same characters. g means "global"
    ".." // Replace with two arbitrary characters
  ).replace( // Replace again...
     /(\*\*|__) // Match ** or __, store in "group 1"
       (?=\S)   // Make sure next character isn't whitespace
       (.*?\S)\1  // Match all characters until "group 1".
                  // Make sure last character isn't whitespace
     /g, l=> // Take the match...
       o+= // Increase o by...
         l.length // the length of the match
         - 4 // minus 4 to account for ** and __
  ), o) // Return o
Downgoat
fuente
Para **a*b*c**esto devuelve 9, que creo que es incorrecto. El recuento real es 5 (o 3, si tiene en cuenta las itálicas, que según OP no debería).
Cristian Lupascu