2012-03-18 11 views
5

Ho problemi lavorazione una regex per abbinare YAML anteriore MatterPython Regex per abbinare YAML anteriore Matter

Questa è la questione davanti stavo cercando di abbinare:

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

Questo è quello che ho pensato funzionerebbe:

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

Qualsiasi aiuto sarebbe molto apprezzato.

+1

State ottenendo spazi bianchi prima o dopo i trattini (---)? Questo lo spezzerebbe. – MrGomez

+0

Ya, è possibile ottenere uno spazio prima/dopo. Se non ti dispiace, come regolerei la mia espressione regolare per gestirlo? – Mitciv

+0

Dato il mio tentativo di rispondere alla domanda, inserirò questo in una risposta. :) – MrGomez

risposta

6

a disfare quello che si sta facendo con questa espressione regolare:

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

  • r: trattare questo come un string literal in Python
  • ^: Avviare la valutazione all'inizio di un riga
  • (---): Analizza --- in un anonimo capture group
  • (.*): Parse tutti i caratteri (.) non-greedily (*) fino alla successiva espressione
  • (---): Come sopra
  • $: End alla valutazione della fine di una linea

Il problema è che questo fallirà quando lo spazio bianco è presente. Stai letteralmente dicendo: trova trattini che si verificano all'inizio di una riga e analizza fino a trovare i trattini che si verificano alla fine di uno. Inoltre, stai creando gruppi che ritengo non siano necessari per l'utile valutazione della tua espressione regolare, usando le parentesi () attorno ai trattini usati per trovare l'argomento YAML.

Un'espressione migliore sarebbe:

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

che aggiunge il gruppo ripetuto \s* catturare caratteri spazio tra l'inizio della prima linea fino a trattini, aggiunge questo nuovo tra il secondo gruppo di trattini alla fine di quella linea, e cattura tutto in un unico gruppo di cattura anonimo che è possibile utilizzare per ulteriori elaborazioni. Se non si desidera estrarre il contenuto della parte anteriore, è sufficiente sostituire (.*) con .*.

Considerare re.findall per più valutazioni di questa espressione regolare in un singolo file e, come accennato, utilizzare re.DOTALL per consentire al carattere punto di corrispondere a nuove righe.

+0

Grazie per l'aiuto! – Mitciv

+0

@Mitciv Nessun problema. In bocca al lupo! – MrGomez

0

ho usato qualcosa di simile regex, 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 

ho anche incontrato python-frontmatter, che ha alcune funzioni aggiuntive di supporto:

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

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