Search code examples
regexm3u8

Capturing header and continue matching - Regex


How to capture header #EXTM3U and continue matching #EXTINF pattern if the header exists.

#EXTM3U
#EXTINF:10.0,
media_w854021192_21533.ts
#EXTINF:10.0,
media_w854021192_21534.ts
#EXTINF:10.0,
media_w854021192_21535.ts

Regex:

(?<HEADER>#EXTM3U)\r?\n(?:#EXTINF:(?<DURATION>\-?\d+\.?\d+),(?<TITLE>.+)?\r?\n(?<URI>\S+))

enter image description here Regex demo

Regex result should look like:

enter image description here


Solution

  • You may use the following regex with preg_match_all:

    '~(?<HEADER>#EXTM3U|\G(?!\A))\R\K#EXTINF:(?<DURATION>-?\d+\.?\d+),(?<TITLE>.+)?\R(?<URI>\S+)~'
    

    See the regex demo

    Details'

    • (?<HEADER>#EXTM3U|\G(?!\A)) - HEADER group matching either #EXTM3U or the end of the previous match (\G(?!\A))
    • \R - a line break
    • \K - a match reset operator discarding the text matched so far
    • #EXTINF: - a substring
    • (?<DURATION>-?\d+\.?\d+) - DURATION group matching an optional -, 1+ digits, an optional . and then 1+ digits
    • , - a comma
    • (?<TITLE>.+)? - an optional TITLE group matching 1+ chars other than line break chars, as many as possible
    • \R - a line break
    • (?<URI>\S+) - an URI group matching 1 or more non-whitespace chars.