Domanda

Ho bisogno di trovare il numero, dentro e fuori i punti timecode e tutte le linee del testo.

9
00:09:48,347 --> 00:09:52,818
- Let's see... what else she's got?
- Yea... ha, ha.

10
00:09:56,108 --> 00:09:58,788
What you got down there, missy?

11
00:09:58,830 --> 00:10:00,811
I wouldn't do that!

12
00:10:03,566 --> 00:10:07,047
-Shit, that's not enough!
-Pull her back!

Attualmente sto usando questo schema, ma dimentica tutto il testo due linee

(?<Order>\d+)\r\n(?<StartTime>(\d\d:){2}\d\d,\d{3}) --> (?<EndTime>(\d\d:){2}\d\d,\d{3})\r\n(?<Sub>.+)(?=\r\n\r\n\d+|$)

Qualsiasi aiuto sarebbe molto apprezzato.

È stato utile?

Soluzione

Credo che ci sono due problemi con l'espressione regolare. La prima è che il . verso la fine di (?<Sub>.+) non corrisponde a capo. Così si potrebbe modificarlo per:

(?<Sub>(.|[\r\n])+?)

In alternativa, è possibile specificare RegexOptions.Singleline come opzione per l'espressione regolare. L'unica cosa che l'opzione non è rendere le nuove righe di punti partita.

Il secondo problema è che .+ corrisponde il maggior numero di linee come si può. Si può rendere non avido come:

(?<Sub>(.|[\r\n])+?(?=\r\n\r\n|$))

Questo corrisponde la minima quantità di testo che termina con una riga vuota o la fine della stringa.

Altri suggerimenti

Se fossi in te, mi piacerebbe un passo indietro da un'implementazione regex-based e guardo una macchina a stati, passeggiando per il file riga per riga. Il formato sembra essere abbastanza semplice da gestire con forse 20-40 righe di codice facile da capire, ma troppo complesso per una regex ragionevole.

Io personalmente dividere le linee in un array e scorrere l'array esame ogni riga, solo facendo un match regex per le StartTime-> linee EndTime, quindi è possibile utilizzare alcuni abbastanza semplice logica per afferrare Order dalla riga precedente, e afferrare il testo dalle linee seguenti (cercando avanti per trovare il prossimo StartTime-> Endtime e backtracking due linee).

Credo che in questo modo braciole il problema un po 'in modo che non si dispone di un'espressione regex cercando di fare tutto.

Sto usando seguente espressione regolare per analizzare i file .srt:

@"(?<number>\d+)\r\n(?<start>\S+)\s-->\s(?<end>\S+)\r\n(?<text>(.|[\r\n])+?)\r\n\r\n"

Regular Expression Language - Quick Reference

Ho usato questa espressione regolare nel mio parser Rubino:

slines.scan(/(^[0-9]+)\r?\n(.*? --> .*?)\r?\n(.*?)(?=^[0-9]+\r?\n|\s+\Z)/im).map{|z| [z[0],[z[1],z[2].strip]]}

dove "slines" è l'intero file dei sottotitoli leggere nella memoria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top