Android 使用正则表达式解析HLS m3u8文件
我想解析HLS主m3u8文件,并从中获取带宽、分辨率和文件名。目前,我正在使用字符串解析来搜索字符串中的一些模式,并执行子字符串以获取值 示例文件:Android 使用正则表达式解析HLS m3u8文件,android,regex,http-live-streaming,m3u8,Android,Regex,Http Live Streaming,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.
#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
但是我发现我们可以用正则表达式解析它,就像这个问题中提到的:
我对正则表达式没有任何概念,所以请有人指导我使用正则表达式解析它
或者有人可以帮我写regexp来解析下面字符串中的带宽和分辨率值吗
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234
您可以尝试以下方法:
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:
开头的字符串,并包含带宽
和分辨率
,后跟正确的值格式。然后在后参考组1和2中对它们进行后参考,以便我们可以提取它们
编辑:
如果分辨率不总是存在,则可以将该部分设置为可选部分:
"^#EXT-X-STREAM-INF:.*BANDWIDTH=(\\d+).*(?:RESOLUTION=([\\dx]+))?.*"
如果只有带宽
,则分辨率
字符串将为null
Edit2:
?
使事物成为可选的,而(?:u________;)表示被动组(相对于反向参考组(____;)而言)。因此它基本上是一个可选的被动组。因此,是的,它里面的任何事物都是可选的
匹配单个字符,而*
makes意味着它将被重复零次或多次。因此*
将匹配零个或多个字符。我们需要这样做的原因是要消耗我们匹配的内容之间的任何内容,例如\EXT-X-STREAM-INF:
和带宽之间的任何内容。有很多但是,*
是最通用/最广泛的方法
\d
基本上是一组表示数字的字符(0-9
),但由于我们将字符串定义为Java字符串,我们需要双\
,否则Java编译器将失败,因为它无法识别转义字符\d
(在Java中)。相反,它将把\\
解析为\
,以便在传递给模式
构造函数的最后一个字符串中获得\d
[\dx]+
表示字符0-9
中的一个或多个字符(+
),而x
[\dx\d]
将是同一组字符中的单个字符(无+
)
如果您对regex感兴趣,您可以查看或/和,在那里您可以找到所有问题的更深入的答案。我发现这个可能会有所帮助。
(许可证:LGPLv3)您可以拆分字符串,下面是我在python中的意思
fu ="#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234"
for chunk in fu.split(':')[1].split(','):
if chunk.startswith('BANDWIDTH'):
bandwidth = int(chunk.split('=')[1])
if chunk.startswith('RESOLUTION'):
resolution = chunk.split('=')[1]
感谢您的回复,我将尝试您的代码。当我们调用pattern.matcher时,我有一个关于模式匹配的问题。matcher
它在matcher
中究竟返回了什么?是字符串在正则表达式中忽略了给定的模式吗?在执行pattern.matcher
之后,我们为什么调用find
?matcher是一个t您用于根据模式对给定字符串执行匹配操作。当您调用find()
时,它将尝试在给定字符串中查找下一个匹配项,如果找到一个匹配项,它将返回true,我们可以提取结果。您可以查看更多信息(这是Java文档,但它在Android上的行为应该相同,Android文档中没有太多细节)。谢谢你的解释!我绑定了你的代码,它正在工作,但如果字符串没有分辨率,只有带宽,那么?我尝试了,但在这种情况下,find
失败。是否可以在任何一种情况下检查分辨率,如果找到,则确定,否则忽略,或者我们需要两个单独的表达式来解析bandwidth和resolution,并将相同的字符串传递给它们,然后调用find?请参阅我的编辑:)只要只有分辨率是可选的,这是直接的,如果您有没有带宽但具有分辨率的实例,那么它会变得有点棘手,但应该仍然可以。更新我的答案以包括您的最新问题。