2013-09-02 25 views
5

Ho sofferto con regex python per un po 'cercando di abbinare i paragrafi all'interno di un testo, ma non ho avuto successo. Devo ottenere le posizioni di inizio e fine dei paragrafi.Come abbinare un paragrafo usando regex

Un esempio di un testo:

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At 
vero eos et accusam et justo duo dolores et ea rebum. 

Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. 

Ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At 
vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. 

In questo caso esemplificativo, vorrei corrispondere separatamente tutti i paragrafi che iniziano con Lorem, Stet e Ipsum rispettivamente (senza le righe vuote). Qualcuno ha qualche idea su come farlo?

+1

C'è una ragione per la quale si vogliono fare questo con regex? Per qualcosa di semplice come dividere i paragrafi delimitati a doppia riga di delimitazione, basta usare 'paragraph.split ('\ n \ n')' –

+0

Sono interessato alle posizioni di inizio e fine dei paragrafi, non alle stringhe attuali. Avrei dovuto dirlo. –

risposta

3

È possibile dividere il doppio ritorno a capo in questo modo:

paragraphs = re.split(r"\n\n", DATA) 

Edit: per catturare i paragrafi come partite, in modo da poter ottenere i loro punti di inizio e fine, fare questo:

for match in re.finditer(r'(?s)((?:[^\n][\n]?)+)', DATA): 
    print match.start(), match.end() 

# Prints: 
# 0 214 
# 215 298 
# 299 589 
+0

Come posso usarlo per ottenere un oggetto match? –

2

Utilizzando spaccatura è un modo, è possibile farlo con l'espressione regolare anche in questo modo:

paragraphs = re.search('(.+?\n\n|.+?$)',TEXT,re.DOTALL) 

.+? è una corrispondenza lenta, corrisponderà alla sottostringa più breve che fa corrispondere l'intera espressione regolare. Altrimenti, corrisponderà semplicemente all'intera stringa.

Quindi, in pratica qui vogliamo trovare una sequenza di caratteri (.+?), che termina con una riga vuota (\n\n) o alla fine della stringa ($). Il flag re.DOTALL rende il punto uguale a newline anche (vogliamo anche abbinare un paragrafo composto da tre righe senza righe vuote all'interno)

+0

Grazie per la risposta. Si noti tuttavia che questo modello corrisponde anche alle linee vuote, che non è corretto. –

0

Qual è il simbolo di nuova riga? Supponiamo il simbolo di nuova riga è '\ r \ n', se si desidera far corrispondere i paragrafi che iniziano con Lorem, si può fare in questo modo:

pattern = re.compile('\r\nLorem.*\r\n') 
str = '...' # your source text 
matchlist = re.findall(pattern, str) 

Il matchlist conterrà avviare tutti i paragragh con Lorem. E le altre due parole sono le stesse.

+0

Il carattere newline in python è solitamente \ n. E il tuo modello non funziona. –

+0

Scusa, ho fatto un errore. Puoi provare questo: 'p = re.compile ('^ Lorem. * \ N') matchlist = re.findall (p, s)' Quindi otterrai l'elenco dei paragrafi che iniziano con Lorem –

0

Prova

^(.+?)\n\s*\n 

o

^(.+?)\r\n\s*\r\n 

solo non dimenticare accodare nuova linea extra alla fine del testo

0

ho cercato di utilizzare la regex consigliato con il motore Java RegEx predefinito . Questo mi ha dato più volte una StackOverflowException, quindi alla fine ho riscritto il RegEx e ottimizzato un po 'di più.

Quindi questo sta lavorando bene per me in Java:

(?s)(.*?[^\:\-\,])(?:$|\n{2,}) 

Questo gestisce anche la fine del documento senza nuove linee e cerca di concat linee che si conclude con ':', '-' o '' al prossimo paragrafo.

E per evitare che gli spazi finali (spazi o tabulazioni) rompe la funzionalità sopra descritta sto li stripping prima con seguente espressione regolare:

(?m)[[:blank:]]+$ 
Problemi correlati