2011-03-16 21 views
6

Nuevo en Python, competente en algunos idiomas, pero no puede ver una manera "elegante" de hacer lo siguiente. Estoy seguro de que está pidiendo a gritos una expresión regular, pero cualquier solución que se me ocurra (utilizando grupos regex y lo que no) se vuelve una locura con bastante rapidez.¿Cómo reemplazar pares de tokens en una cadena?

Por lo tanto, tengo una cadena con etiquetas html que quiero reemplazar con etiquetas html reales.

Por ejemplo:

Hello, my name is /bJane/b. 

debe convertirse en:

Hello, my name is <b>Jane</b>. 

Se podría combo'd con talic [i] y [u] nderline así:

/iHello/i, my /uname/u is /b/i/uJane/b/i/u. 

Debe convertirse en:

<i>Hello</i>, my <u>name</u> is <b><i><u>Jane</b></i></u>. 

Obviamente, un reemplazo directo no funcionará porque cada 2 token debe ir precedido por la barra lateral.

Para mayor claridad, si se combinan los tokens, siempre se abren primero, primero se cierran.

¡Muchas gracias!

PD: Antes de que nadie se excita, sé que este tipo de cosas debe hacerse con CSS, bla, bla, bla, pero no escribí el software, sólo estoy invirtiendo su salida!

+6

Si se supone que es HTML, no es válido porque sus elementos son superposición. Creo que lo que quería decir es ' Jane' pero eso podría ser más difícil de hacer correctamente. –

+0

Soy consciente de que no es HTML válido, pero eso no importa. Solo estaba buscando un analizador rápido y sucio para la salida de una aplicación (nuevo para Python, así que pensé en probarlo). El resultado del análisis solo se está utilizando en casa para notas. – Bridgey

+0

"... solo se está utilizando en casa para notas" - ¿podemos mantenerlo así? :) –

Respuesta

7

Tal vez algo como esto puede ayudar:

import re 


def text2html(text): 
    """ Convert a text in a certain format to html. 

    Examples: 
    >>> text2html('Hello, my name is /bJane/b') 
    'Hello, my name is <b>Jane</b>' 
    >>> text2html('/iHello/i, my /uname/u is /b/i/uJane/u/i/b') 
    '<i>Hello</i>, my <u>name</u> is <b><i><u>Jane</u></i></b>' 

    """ 

    elem = [] 

    def to_tag(match_obj): 
     match = match_obj.group(0) 
     if match in elem: 
      elem.pop(elem.index(match)) 
      return "</{0}>".format(match[1]) 
     else: 
      elem.append(match) 
      return "<{0}>".format(match[1]) 

    return re.sub(r'/.', to_tag, text) 

if __name__ == "__main__": 
    import doctest 
    doctest.testmod() 
+0

¡Impresionante, muchas gracias! ¡Eso parece funcionar como un regalo! – Bridgey

+0

@Bridgey: me alegro de que me ayudes :) – mouad

0

con SED:

s/\/([biu])([^/]\+)\/\1/<\1>\2<\/\1>/g 
+0

Escribir solo es correcto. Ve expresiones regulares. – nmichaels

+0

, ya que mencionó a python, no parece ser tan útil con una solución sed. –

+0

Gracias chicos. Disculpe mi ignorancia de python/sed, pero sé sed como un comando linux/unix, no como parte de Python. Dado que me gustaría que la secuencia de comandos de python también se pueda ejecutar en Windows, ¿funcionará esto? – Bridgey

0

Una solución muy sencilla sería la de dividir la cadena usando la etiqueta de fuente '/ b' y reunirse con la matriz de subcadena con la nueva etiqueta de destino '' de esta manera:

s = "Hello, my name is /bJane/b." 
'<b>'.join(s.split('/b')) 
print s 

'Hello, my name is <b>Jane<b>.' 
+0

Te falta el '/' en la etiqueta de cierre. – Johnsyweb

Cuestiones relacionadas