2009-08-26 21 views
14

No he podido encontrar un buen ejemplo de subclases de cadena.Template en Python, aunque he visto varias referencias para hacerlo en la documentación.Ejemplo de subclases de cadena.Plantilla en Python?

¿Hay algún ejemplo de esto en la web?

Quiero cambiar $ para que sea un personaje diferente y quizás cambie la expresión regular para los identificadores.

+0

Una nota es que no debe intentar hacer esto en Cython. No funciona No estoy seguro de la razón. –

Respuesta

22

De pitón docs:

uso avanzado: se puede derivar subclases de plantilla para personalizar la sintaxis marcador de posición, delimitador carácter, o todo el expresión regular se utiliza para analizar la plantilla cuerdas. Para ello, puede anular estos atributos de clase:

  • delimitador - Esta es la cadena literal que describe la introducción de un delimitador marcador de posición . El valor por defecto $. Tenga en cuenta que esto no debe ser una expresión regular, ya que la implementación llamará a re.escape() en esta cadena, según sea necesario.

  • idpattern - Esta es la expresión regular que describe el patrón para marcadores de posición no arriostrados (los tirantes se añadirá automáticamente como apropiado). El valor predeterminado es la expresión regular [_a-z] [_ a-z0-9] *.

Ejemplo:

from string import Template 

class MyTemplate(Template): 
    delimiter = '#' 
    idpattern = r'[a-z][_a-z0-9]*' 

>>> s = MyTemplate('#who likes $what') 
>>> s.substitute(who='tim', what='kung pao') 
'tim likes $what' 

en Python 3:

Nuevo en la versión 3.2.

Como alternativa, puede proporcionar el patrón de expresión regular completo anulando el patrón de atributo de clase. Si hace esto, el valor debe ser un objeto de expresión regular con cuatro grupos de captura nombrados. Los grupos de captura corresponden a las reglas dadas anteriormente, junto con la regla de marcador de posición no válida:

  • escaparon - Este grupo coincide con la secuencia de escape, por ejemplo $$, en el patrón predeterminado.
  • named - Este grupo coincide con el nombre del marcador de posición sin filo; no debe incluir el delimitador en el grupo de captura.
  • arriostrado: este grupo coincide con el nombre del marcador de posición incluido; no debe incluir ni el delimitador ni las llaves en el grupo de captura .
  • no válido - Este grupo coincide con cualquier otro patrón de delimitador (generalmente un único delimitador), y debe aparecer al final en la expresión normal .

Ejemplo:

from string import Template 
import re 

class TemplateClone(Template): 
    delimiter = '$' 
    pattern = r''' 
    \$(?: 
     (?P<escaped>\$) | # Escape sequence of two delimiters 
     (?P<named>[_a-z][_a-z0-9]*)  | # delimiter and a Python identifier 
     {(?P<braced>[_a-z][_a-z0-9]*)} | # delimiter and a braced identifier 
     (?P<invalid>)    # Other ill-formed delimiter exprs 
    ) 
    ''' 

class TemplateAlternative(Template): 
    delimiter = '[-' 
    pattern = r''' 
    \[-(?: 
     (?P<escaped>-) |   # Expression [-- will become [- 
     (?P<named>[^\[\]\n-]+)-\] | # -, [, ], and \n can't be used in names 
     \b\B(?P<braced>) |   # Braced names disabled 
     (?P<invalid>)    # 
    ) 
    ''' 

>>> t = TemplateClone("$hi sir") 
>>> t.substitute({"hi": "hello"}) 
'hello sir' 

>>> ta = TemplateAlternative("[-hi-] sir") 
>>> ta.substitute({"hi": "have a nice day"}) 
'have a nice day sir' 
>>> ta = TemplateAlternative("[--[-hi-]-]") 
>>> ta.substitute({"hi": "have a nice day"}) 
'[-have a nice day-]' 

Aparentemente también es posible simplemente omitir cualquiera de los grupos de expresiones regulares escaped, named, braced o invalid para desactivarlo.

+0

¿sabes cómo sucede esto en el fondo? en otras palabras, ¿cómo se reemplaza el delímetro con '#'? – slopeofhope