2013-03-07 4 views
3

Я хочу разобрать файл HLS master m3u8 и получить от него ширину полосы пропускания, разрешение и имя файла. В настоящее время я использую синтаксический анализ строк для поиска строки для некоторых шаблонов и для получения значения используется вспомогательная строка.Parsing HLS m3u8 файл с использованием регулярных выражений

Пример файла:

#EXTM3U 
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234 
Stream1/index.m3u8 
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=763319,RESOLUTION=480x270 
Stream2/index.m3u8 
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1050224,RESOLUTION=640x360 
Stream3/index.m3u8 
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1910937,RESOLUTION=640x360 
Stream4/index.m3u8 
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3775816,RESOLUTION=1280x720 
Stream5/index.m3u8 

Но я обнаружил, что мы можем разобрать его с помощью регулярных выражений, как упомянуто в этом вопросе: Problem matching regex pattern in Android

я не имею ни малейшего представления регулярного выражения так может некоторые один из них поможет мне разобрать это, используя регулярное выражение.

Или кто-то может помочь мне в написании регулярного выражения для разбора из BANDWIDTH и разрешения значения из ниже строк

#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234 

ответ

8

Вы могли бы попробовать что-то вроде этого:

final Pattern pattern = Pattern.compile("^#EXT-X-STREAM-INF:.*BANDWIDTH=(\\d+).*RESOLUTION=([\\dx]+).*"); 

    Matcher matcher = pattern.matcher("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234"); 
    String bandwidth = ""; 
    String resolution = ""; 

    if (matcher.find()) { 
     bandwidth = matcher.group(1); 
     resolution = matcher.group(2); 
    } 

бы установить пропускную способность и разрешение на правильные (String) значения.

Я не пробовал это на устройстве или эмуляторе Android, но, судя по ссылке, которую вы отправили, и API Android, он должен работать так же, как и предыдущая простая Java.

Регулярное выражение соответствует строкам, начиная с #EXT-X-STREAM-INF: и содержит BANDWIDTH и RESOLUTION, за которым следует правильные форматы значений. Затем они обращаются назад в справочную группу 1 и 2, поэтому мы можем их извлечь.

Edit:

Если разрешение не всегда присутствует, то вы можете сделать эту часть необязательно как таковой:

"^#EXT-X-STREAM-INF:.*BANDWIDTH=(\\d+).*(?:RESOLUTION=([\\dx]+))?.*" 

Строка resolution будет в тех случаях, когда только BANDWIDTH присутствует null.

Edit2:..

? делает вещи по желанию, и (?:___) означает пассивную группу (в противоположность обратной референтной группы (___) Так что это в основном факультативный пассивная группа Так что да, все, что в нем будет необязательными.

. соответствует одному символу, и * делает означает, что она будет повторяться ноль или более раз. Так .* будут соответствовать ноль или более символов. причина нам это нужно потреблять что-нибудь между тем, что мы соответствие , например, любой г между #EXT-X-STREAM-INF: и BANDWIDTH. Существует много способов сделать это, но .* является наиболее общим/широким.

\d в основном набор символов, которые представляют число (0-9), но так как мы задаем строку в виде строки Java, нам нужны двойная \\, в противном случае компилятор Java будет не потому, что он не признает сбежавший характер \d (на Java).Вместо этого он будет разбирать \\ в \, чтобы мы получили \d в последней строке, переданной в конструктор Pattern.

[\dx]+ означает один или несколько символов (+) из символов 0-9 и x. [\dx\d] будет единственным символом (не +) из того же набора символов.

Если вас интересует регулярное выражение, вы можете проверить regular-expressions.info или/regexone.com, там вы найдете более подробные ответы на все ваши вопросы.

+0

Спасибо за ответ будет попробовать ваш код. У меня есть вопросы о совпадении шаблонов, когда мы называем 'pattern.matcher', что именно он возвращает в' matcher', является ли строка, опуская данный паттен в регулярном выражении? после выполнения 'pattern.matcher', почему мы вызываем' find'? – User7723337

+1

Матчи - это объект, который вы используете для выполнения соответствующих операций над данной строкой на основе шаблона. Когда вы вызываете 'find()', он попытается найти следующее совпадение в данной строке, если оно найдет одно, оно вернет true, и мы можем извлечь результат. Вы можете посмотреть [документацию] (http://docs.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html) для получения дополнительной информации (то есть документации Java, но он должен вести себя одинаково на Android, в андроид-доке не было много деталей). – rvalvik

+0

спасибо за объяснение! Я связал ваш код, он работает, но в случае, если строка не имеет РЕШЕНИЯ в ней и просто пропускная способность, то? Я попробовал, но «найти» в этом случае не работает. можно ли проверить RESOLUTION в любом случае, если он был найден, тогда все остальное просто игнорируется или нам нужно иметь отдельные выражения для анализа ширины полосы пропускания и разрешения и передавать одну и ту же строку в оба из них и вызвать find? – User7723337