2012-03-18 27 views
5

Tengo problemas para la elaboración de una expresión regular para que coincida con YAML Letra pequeñaPython expresión regular para que coincida con YAML Letra pequeña

Este es el texto preliminar que estaba tratando de igualar:

--- 
    name: me 
    title: test 
    cpu: 1 
    --- 

Esto es lo que pensaba funcionaría:

re.search(r'^(---)(.*)(---)$', content, re.MULTILINE) 

Cualquier ayuda sería muy apreciada.

+1

¿Usted está consiguiendo un espacio en blanco antes o después de los guiones (---)? Eso lo rompería. – MrGomez

+0

Ya, es posible obtener espacios en blanco antes/después. Si no te importa, ¿cómo ajustaría mi expresión regular para manejar eso? – Mitciv

+0

Teniendo en cuenta mis intentos de responder a la pregunta, voy a rodar esto en una respuesta. :) – MrGomez

Respuesta

6

para desempaquetar lo que está haciendo actualmente con esta expresión regular:

r'^(---)(.*)(---)$':

  • r: tratar esto como una string literal in Python
  • ^: Iniciar la evaluación al comienzo de una línea
  • (---): Parse --- en un anónimo capture group
  • (.*): Parse todos los caracteres (.) non-greedily (*) hasta la siguiente expresión
  • (---): Como arriba
  • $: End en la evaluación de la final de una línea

El problema es que esto fallará cuando el espacio en blanco esté presente. Estás diciendo literalmente: encuentra guiones que aparecen al comienzo de una línea y analiza hasta que encontremos guiones que aparecen al final de uno. Además, está creando grupos que creo que no son necesarios para la evaluación útil de su expresión regular, mediante el uso de paréntesis () alrededor de los guiones utilizados para encontrar la materia prima YAML.

una mejor expresión sería:

r'^\s*---(.*)---\s*$'

que añade el grupo de repetición \s* para capturar caracteres de espacio en blanco entre el comienzo de la primera línea hasta los guiones, añade este nuevo entre el segundo grupo de guiones hasta el final de esa línea, y captura todo en un solo grupo de captura anónima que luego puede usar para un procesamiento adicional. Si no se desea extraer el contenido del frente, simplemente reemplace (.*) con .*.

Considere re.findall para realizar múltiples evaluaciones de esta expresión regular en un solo archivo, y como se mencionó, use re.DOTALL para permitir que el carácter de punto coincida con las líneas nuevas.

+0

¡Gracias por la ayuda! – Mitciv

+0

@Mitciv No hay problema. ¡Buena suerte! – MrGomez

0

que he usado algo como esto expresiones regulares, re.findall('^---[\s\S]+?---', text):

def extractFrontMatter(markdown): 
    md = open(markdown, 'r') 
    text = md.read() 
    md.close() 
    # Returns first yaml content, `--- yaml frontmatter ---` from the .md file 
    # http://regexr.com/3f5la 
    # https://stackoverflow.com/questions/2503413/regular-expression-to-stop-at-first-match 
    match = re.findall('^---[\s\S]+?---', text) 
    if match: 
     # Strips `---` to create a valid yaml object 
     ymd = match[0].replace('---', '') 
     try: 
      return yaml.load(ymd) 
     except yaml.YAMLError as exc: 
      print exc 

también me he encontrado con python-frontmatter, que tiene algunas funciones auxiliares adicionales:

import frontmatter 
post = frontmatter.load('/path/to-markdown.md') 

print post.metadata, 'meta' 
print post.keys(), 'keys' 
Cuestiones relacionadas