2013-03-07 30 views
3

我想解析HLS主m3u8文件并从中获取带宽,分辨率和文件名。目前我使用字符串解析来搜索字符串的一些模式,并做子字符串来获取价值。使用正则表达式解析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

我没有正则表达式的任何想法,所以会有些一个请指导我使用正则表达式来解析此问题。

或者有人可以帮我写的正则表达式从以下字符串

#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); 
    } 

会设置带宽和分辨率的正确(字符串)值。

我还没有尝试过这个在Android设备或模拟器上,但从你发送的链接和android API来看,它应该像上面的普通老Java一样工作。

该正则表达式匹配以#EXT-X-STREAM-INF:开头的字符串,其中包含BANDWIDTHRESOLUTION,后跟正确的值格式。然后这些在后向参照组1和2中被反引用,以便我们可以提取它们。

编辑:

如果分辨率不总是存在,那么你就可以说部分可选的,因为这样的:

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

resolution字符串在只有BANDWIDTH存在的情况下null

EDIT2:。

?使事情可选的,(?:___)意味着被动组(而不是反向引用组(___)所以它基本上是一个可选的被动组所以,是的,它里面什么会可选。

一个.匹配单个字符,和*使得意味着它会被重复零次或多次。所以.*将匹配零个或多个字符。我们需要的原因,这是消耗我们所匹配之间的任何,例如anythin g在#EXT-X-STREAM-INF:BANDWIDTH之间。有很多方法可以做到这一点,但.*是最通用/最广泛的方法。

\d基本上是一组表示数字(0-9)字符,但由于我们定义字符串作为一个Java字符串,我们需要加倍\\,否则Java编译器将失败,因为它不承认的转义字符\d (用Java)。相反,它会将\\解析为\,以便我们在传递给Pattern构造函数的最后一个字符串中获得\d

[\dx]+表示字符中的一个或多个字符(+0-9x[\dx\d]将是同一组字符中的单个字符(不是+)。

如果你有兴趣的正则表达式,你可以检查出regular-expressions.info或/和regexone.com,那么你会发现更多的深入解答所有的问题。

+0

感谢您的答复将尝试您的代码。当我们调用'pattern.matcher'时,我有一个关于模式匹配的问题,它在'matcher'中返回的是它在正则表达式中忽略给定的模式的字符串?在做'pattern.matcher'之后,我们为什么要调用'find'? – User7723337 2013-03-07 08:58:45

+1

匹配器是您用来根据模式对给定字符串执行匹配操作的对象。当你调用find()时,它会尝试找到给定字符串中的下一个匹配项,如果它找到一个它返回true,我们可以提取结果。您可以查看[文档](http://docs.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html)以获取更多信息(这是Java文档,但是它应该在Android上表现相同的方式,android文档没有太多细节)。 – rvalvik 2013-03-07 09:13:49

+0

感谢您的解释!我把你的代码绑定在工作,但如果字符串没有解决方案,只是带宽呢?我尝试过,但'find'在这种情况下失败了。是否有可能检查解决方案在任何情况下,如果发现然后确定否则只是忽略或我们需要拖放单独的表达式来解析带宽和分辨率,并将相同的字符串传递给它们并调用find? – User7723337 2013-03-07 09:34:44